diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0272-drm-amd-display-Add-DCE12-bios-parser-support.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.14.71/0272-drm-amd-display-Add-DCE12-bios-parser-support.patch | 3989 |
1 files changed, 0 insertions, 3989 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0272-drm-amd-display-Add-DCE12-bios-parser-support.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0272-drm-amd-display-Add-DCE12-bios-parser-support.patch deleted file mode 100644 index db5f644f..00000000 --- a/common/recipes-kernel/linux/linux-yocto-4.14.71/0272-drm-amd-display-Add-DCE12-bios-parser-support.patch +++ /dev/null @@ -1,3989 +0,0 @@ -From 4be1f3c0a235197dba29743dcbb84a34ae9101c3 Mon Sep 17 00:00:00 2001 -From: Harry Wentland <harry.wentland@amd.com> -Date: Mon, 6 Mar 2017 14:29:52 -0500 -Subject: [PATCH 0272/4131] drm/amd/display: Add DCE12 bios parser support - -Signed-off-by: Harry Wentland <harry.wentland@amd.com> -Signed-off-by: Alex Deucher <alexander.deucher@amd.com> ---- - 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_disp_power_gating( -+ struct dc_bios *dcb, -+ enum controller_id controller_id, -+ enum bp_pipe_control_action action) -+{ -+ struct bios_parser *bp = BP_FROM_DCB(dcb); -+ -+ if (!bp->cmd_tbl.enable_disp_power_gating) -+ return BP_RESULT_FAILURE; -+ -+ return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id, -+ action); -+} -+ -+static bool bios_parser_is_accelerated_mode( -+ struct dc_bios *dcb) -+{ -+ return bios_is_accelerated_mode(dcb); -+} -+ -+ -+/** -+ * bios_parser_set_scratch_critical_state -+ * -+ * @brief -+ * update critical state bit in VBIOS scratch register -+ * -+ * @param -+ * bool - to set or reset state -+ */ -+static void bios_parser_set_scratch_critical_state( -+ struct dc_bios *dcb, -+ bool state) -+{ -+ bios_set_scratch_critical_state(dcb, state); -+} -+ -+static enum bp_result bios_parser_get_firmware_info( -+ struct dc_bios *dcb, -+ struct firmware_info *info) -+{ -+ struct bios_parser *bp = BP_FROM_DCB(dcb); -+ enum bp_result result = BP_RESULT_BADBIOSTABLE; -+ struct atom_common_table_header *header; -+ -+ struct atom_data_revision revision; -+ -+ if (info && DATA_TABLES(firmwareinfo)) { -+ header = GET_IMAGE(struct atom_common_table_header, -+ DATA_TABLES(firmwareinfo)); -+ get_atom_data_table_revision(header, &revision); -+ switch (revision.major) { -+ case 3: -+ switch (revision.minor) { -+ case 1: -+ result = get_firmware_info_v3_1(bp, info); -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return result; -+} -+ -+static enum bp_result get_firmware_info_v3_1( -+ struct bios_parser *bp, -+ struct firmware_info *info) -+{ -+ struct atom_firmware_info_v3_1 *firmware_info; -+ struct atom_display_controller_info_v4_1 *dce_info = NULL; -+ -+ if (!info) -+ return BP_RESULT_BADINPUT; -+ -+ firmware_info = GET_IMAGE(struct atom_firmware_info_v3_1, -+ DATA_TABLES(firmwareinfo)); -+ -+ dce_info = GET_IMAGE(struct atom_display_controller_info_v4_1, -+ DATA_TABLES(dce_info)); -+ -+ if (!firmware_info || !dce_info) -+ return BP_RESULT_BADBIOSTABLE; -+ -+ memset(info, 0, sizeof(*info)); -+ -+ /* Pixel clock pll information. */ -+ /* We need to convert from 10KHz units into KHz units */ -+ info->default_memory_clk = firmware_info->bootup_mclk_in10khz * 10; -+ info->default_engine_clk = firmware_info->bootup_sclk_in10khz * 10; -+ -+ /* 27MHz for Vega10: */ -+ info->pll_info.crystal_frequency = dce_info->dce_refclk_10khz * 10; -+ -+ /* Hardcode frequency if BIOS gives no DCE Ref Clk */ -+ if (info->pll_info.crystal_frequency == 0) -+ info->pll_info.crystal_frequency = 27000; -+ -+ info->dp_phy_ref_clk = dce_info->dpphy_refclk_10khz * 10; -+ info->i2c_engine_ref_clk = dce_info->i2c_engine_refclk_10khz * 10; -+ -+ /* Get GPU PLL VCO Clock */ -+ -+ if (bp->cmd_tbl.get_smu_clock_info != NULL) { -+ /* VBIOS gives in 10KHz */ -+ info->smu_gpu_pll_output_freq = -+ bp->cmd_tbl.get_smu_clock_info(bp) * 10; -+ } -+ -+ return BP_RESULT_OK; -+} -+ -+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) -+{ -+ struct bios_parser *bp = BP_FROM_DCB(dcb); -+ struct atom_display_object_path_v2 *object; -+ struct atom_encoder_caps_record *record = NULL; -+ -+ if (!info) -+ return BP_RESULT_BADINPUT; -+ -+ object = get_bios_object(bp, object_id); -+ -+ if (!object) -+ return BP_RESULT_BADINPUT; -+ -+ record = get_encoder_cap_record(bp, object); -+ if (!record) -+ return BP_RESULT_NORECORD; -+ -+ info->DP_HBR2_CAP = (record->encodercaps & -+ ATOM_ENCODER_CAP_RECORD_HBR2) ? 1 : 0; -+ info->DP_HBR2_EN = (record->encodercaps & -+ ATOM_ENCODER_CAP_RECORD_HBR2_EN) ? 1 : 0; -+ info->DP_HBR3_EN = (record->encodercaps & -+ ATOM_ENCODER_CAP_RECORD_HBR3_EN) ? 1 : 0; -+ info->HDMI_6GB_EN = (record->encodercaps & -+ ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN) ? 1 : 0; -+ -+ return BP_RESULT_OK; -+} -+ -+ -+static struct atom_encoder_caps_record *get_encoder_cap_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 = object->encoder_recordoffset + bp->object_info_tbl_offset; -+ -+ for (;;) { -+ header = GET_IMAGE(struct atom_common_record_header, offset); -+ -+ if (!header) -+ return NULL; -+ -+ offset += header->record_size; -+ -+ if (header->record_type == LAST_RECORD_TYPE || -+ !header->record_size) -+ break; -+ -+ if (header->record_type != ATOM_ENCODER_CAP_RECORD_TYPE) -+ continue; -+ -+ if (sizeof(struct atom_encoder_caps_record) <= -+ header->record_size) -+ return (struct atom_encoder_caps_record *)header; -+ } -+ -+ return NULL; -+} -+ -+/* -+ * get_integrated_info_v11 -+ * -+ * @brief -+ * Get V8 integrated BIOS information -+ * -+ * @param -+ * bios_parser *bp - [in]BIOS parser handler to get master data table -+ * integrated_info *info - [out] store and output integrated info -+ * -+ * @return -+ * enum bp_result - BP_RESULT_OK if information is available, -+ * BP_RESULT_BADBIOSTABLE otherwise. -+ */ -+static enum bp_result get_integrated_info_v11( -+ struct bios_parser *bp, -+ struct integrated_info *info) -+{ -+ struct atom_integrated_system_info_v1_11 *info_v11; -+ uint32_t i; -+ -+ info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11, -+ DATA_TABLES(integratedsysteminfo)); -+ -+ if (info_v11 == NULL) -+ return BP_RESULT_BADBIOSTABLE; -+ -+ info->gpu_cap_info = -+ le32_to_cpu(info_v11->gpucapinfo); -+ /* -+ * system_config: Bit[0] = 0 : PCIE power gating disabled -+ * = 1 : PCIE power gating enabled -+ * Bit[1] = 0 : DDR-PLL shut down disabled -+ * = 1 : DDR-PLL shut down enabled -+ * Bit[2] = 0 : DDR-PLL power down disabled -+ * = 1 : DDR-PLL power down enabled -+ */ -+ info->system_config = le32_to_cpu(info_v11->system_config); -+ info->cpu_cap_info = le32_to_cpu(info_v11->cpucapinfo); -+ info->memory_type = info_v11->memorytype; -+ info->ma_channel_number = info_v11->umachannelnumber; -+ info->lvds_ss_percentage = -+ le16_to_cpu(info_v11->lvds_ss_percentage); -+ info->lvds_sspread_rate_in_10hz = -+ le16_to_cpu(info_v11->lvds_ss_rate_10hz); -+ info->hdmi_ss_percentage = -+ le16_to_cpu(info_v11->hdmi_ss_percentage); -+ info->hdmi_sspread_rate_in_10hz = -+ le16_to_cpu(info_v11->hdmi_ss_rate_10hz); -+ info->dvi_ss_percentage = -+ le16_to_cpu(info_v11->dvi_ss_percentage); -+ info->dvi_sspread_rate_in_10_hz = -+ le16_to_cpu(info_v11->dvi_ss_rate_10hz); -+ info->lvds_misc = info_v11->lvds_misc; -+ for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) { -+ info->ext_disp_conn_info.gu_id[i] = -+ info_v11->extdispconninfo.guid[i]; -+ } -+ -+ for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) { -+ info->ext_disp_conn_info.path[i].device_connector_id = -+ object_id_from_bios_object_id( -+ le16_to_cpu(info_v11->extdispconninfo.path[i].connectorobjid)); -+ -+ info->ext_disp_conn_info.path[i].ext_encoder_obj_id = -+ object_id_from_bios_object_id( -+ le16_to_cpu( -+ info_v11->extdispconninfo.path[i].ext_encoder_objid)); -+ -+ info->ext_disp_conn_info.path[i].device_tag = -+ le16_to_cpu( -+ info_v11->extdispconninfo.path[i].device_tag); -+ info->ext_disp_conn_info.path[i].device_acpi_enum = -+ le16_to_cpu( -+ info_v11->extdispconninfo.path[i].device_acpi_enum); -+ info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index = -+ info_v11->extdispconninfo.path[i].auxddclut_index; -+ info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index = -+ info_v11->extdispconninfo.path[i].hpdlut_index; -+ info->ext_disp_conn_info.path[i].channel_mapping.raw = -+ info_v11->extdispconninfo.path[i].channelmapping; -+ } -+ info->ext_disp_conn_info.checksum = -+ info_v11->extdispconninfo.checksum; -+ -+ /** TODO - review **/ -+ #if 0 -+ info->boot_up_engine_clock = le32_to_cpu(info_v11->ulBootUpEngineClock) -+ * 10; -+ info->dentist_vco_freq = le32_to_cpu(info_v11->ulDentistVCOFreq) * 10; -+ info->boot_up_uma_clock = le32_to_cpu(info_v8->ulBootUpUMAClock) * 10; -+ -+ for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { -+ /* Convert [10KHz] into [KHz] */ -+ info->disp_clk_voltage[i].max_supported_clk = -+ le32_to_cpu(info_v11->sDISPCLK_Voltage[i]. -+ ulMaximumSupportedCLK) * 10; -+ info->disp_clk_voltage[i].voltage_index = -+ le32_to_cpu(info_v11->sDISPCLK_Voltage[i].ulVoltageIndex); -+ } -+ -+ info->boot_up_req_display_vector = -+ le32_to_cpu(info_v11->ulBootUpReqDisplayVector); -+ info->boot_up_nb_voltage = -+ le16_to_cpu(info_v11->usBootUpNBVoltage); -+ info->ext_disp_conn_info_offset = -+ le16_to_cpu(info_v11->usExtDispConnInfoOffset); -+ info->gmc_restore_reset_time = -+ le32_to_cpu(info_v11->ulGMCRestoreResetTime); -+ info->minimum_n_clk = -+ le32_to_cpu(info_v11->ulNbpStateNClkFreq[0]); -+ for (i = 1; i < 4; ++i) -+ info->minimum_n_clk = -+ info->minimum_n_clk < -+ le32_to_cpu(info_v11->ulNbpStateNClkFreq[i]) ? -+ info->minimum_n_clk : le32_to_cpu( -+ info_v11->ulNbpStateNClkFreq[i]); -+ -+ info->idle_n_clk = le32_to_cpu(info_v11->ulIdleNClk); -+ info->ddr_dll_power_up_time = -+ le32_to_cpu(info_v11->ulDDR_DLL_PowerUpTime); -+ info->ddr_pll_power_up_time = -+ le32_to_cpu(info_v11->ulDDR_PLL_PowerUpTime); -+ info->pcie_clk_ss_type = le16_to_cpu(info_v11->usPCIEClkSSType); -+ info->max_lvds_pclk_freq_in_single_link = -+ le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink); -+ info->max_lvds_pclk_freq_in_single_link = -+ le16_to_cpu(info_v11->usMaxLVDSPclkFreqInSingleLink); -+ info->lvds_pwr_on_seq_dig_on_to_de_in_4ms = -+ info_v11->ucLVDSPwrOnSeqDIGONtoDE_in4Ms; -+ info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms = -+ info_v11->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms; -+ info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms = -+ info_v11->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms; -+ info->lvds_pwr_off_seq_vary_bl_to_de_in4ms = -+ info_v11->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms; -+ info->lvds_pwr_off_seq_de_to_dig_on_in4ms = -+ info_v11->ucLVDSPwrOffSeqDEtoDIGON_in4Ms; -+ info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms = -+ info_v11->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms; -+ info->lvds_off_to_on_delay_in_4ms = -+ info_v11->ucLVDSOffToOnDelay_in4Ms; -+ info->lvds_bit_depth_control_val = -+ le32_to_cpu(info_v11->ulLCDBitDepthControlVal); -+ -+ for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) { -+ /* Convert [10KHz] into [KHz] */ -+ info->avail_s_clk[i].supported_s_clk = -+ le32_to_cpu(info_v11->sAvail_SCLK[i].ulSupportedSCLK) -+ * 10; -+ info->avail_s_clk[i].voltage_index = -+ le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageIndex); -+ info->avail_s_clk[i].voltage_id = -+ le16_to_cpu(info_v11->sAvail_SCLK[i].usVoltageID); -+ } -+ #endif /* TODO*/ -+ -+ return BP_RESULT_OK; -+} -+ -+ -+/* -+ * construct_integrated_info -+ * -+ * @brief -+ * Get integrated BIOS information based on table revision -+ * -+ * @param -+ * bios_parser *bp - [in]BIOS parser handler to get master data table -+ * integrated_info *info - [out] store and output integrated info -+ * -+ * @return -+ * enum bp_result - BP_RESULT_OK if information is available, -+ * BP_RESULT_BADBIOSTABLE otherwise. -+ */ -+static enum bp_result construct_integrated_info( -+ struct bios_parser *bp, -+ struct integrated_info *info) -+{ -+ enum bp_result result = BP_RESULT_BADBIOSTABLE; -+ -+ struct atom_common_table_header *header; -+ struct atom_data_revision revision; -+ -+ struct clock_voltage_caps temp = {0, 0}; -+ uint32_t i; -+ uint32_t j; -+ -+ if (info && DATA_TABLES(integratedsysteminfo)) { -+ header = GET_IMAGE(struct atom_common_table_header, -+ DATA_TABLES(integratedsysteminfo)); -+ -+ get_atom_data_table_revision(header, &revision); -+ -+ /* Don't need to check major revision as they are all 1 */ -+ switch (revision.minor) { -+ case 11: -+ result = get_integrated_info_v11(bp, info); -+ break; -+ default: -+ return result; -+ } -+ } -+ -+ if (result != BP_RESULT_OK) -+ return result; -+ -+ /* Sort voltage table from low to high*/ -+ for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) { -+ for (j = i; j > 0; --j) { -+ if (info->disp_clk_voltage[j].max_supported_clk < -+ info->disp_clk_voltage[j-1].max_supported_clk -+ ) { -+ /* swap j and j - 1*/ -+ temp = info->disp_clk_voltage[j-1]; -+ info->disp_clk_voltage[j-1] = -+ info->disp_clk_voltage[j]; -+ info->disp_clk_voltage[j] = temp; -+ } -+ } -+ } -+ -+ return result; -+} -+ -+static struct integrated_info *bios_parser_create_integrated_info( -+ struct dc_bios *dcb) -+{ -+ struct bios_parser *bp = BP_FROM_DCB(dcb); -+ struct integrated_info *info = NULL; -+ -+ info = dm_alloc(sizeof(struct integrated_info)); -+ -+ if (info == NULL) { -+ ASSERT_CRITICAL(0); -+ return NULL; -+ } -+ -+ if (construct_integrated_info(bp, info) == BP_RESULT_OK) -+ return info; -+ -+ dm_free(info); -+ -+ return NULL; -+} -+ -+static const struct dc_vbios_funcs vbios_funcs = { -+ .get_connectors_number = bios_parser_get_connectors_number, -+ -+ .get_encoder_id = bios_parser_get_encoder_id, -+ -+ .get_connector_id = bios_parser_get_connector_id, -+ -+ .get_dst_number = bios_parser_get_dst_number, -+ -+ .get_src_obj = bios_parser_get_src_obj, -+ -+ .get_dst_obj = bios_parser_get_dst_obj, -+ -+ .get_i2c_info = bios_parser_get_i2c_info, -+ -+ .get_voltage_ddc_info = bios_parser_get_voltage_ddc_info, -+ -+ .get_thermal_ddc_info = bios_parser_get_thermal_ddc_info, -+ -+ .get_hpd_info = bios_parser_get_hpd_info, -+ -+ .get_device_tag = bios_parser_get_device_tag, -+ -+ .get_firmware_info = bios_parser_get_firmware_info, -+ -+ .get_spread_spectrum_info = bios_parser_get_spread_spectrum_info, -+ -+ .get_ss_entry_number = bios_parser_get_ss_entry_number, -+ -+ .get_embedded_panel_info = bios_parser_get_embedded_panel_info, -+ -+ .get_gpio_pin_info = bios_parser_get_gpio_pin_info, -+ -+ .get_encoder_cap_info = bios_parser_get_encoder_cap_info, -+ -+ .is_device_id_supported = bios_parser_is_device_id_supported, -+ -+ -+ -+ .is_accelerated_mode = bios_parser_is_accelerated_mode, -+ -+ .set_scratch_critical_state = bios_parser_set_scratch_critical_state, -+ -+ -+/* COMMANDS */ -+ .encoder_control = bios_parser_encoder_control, -+ -+ .transmitter_control = bios_parser_transmitter_control, -+ -+ .enable_crtc = bios_parser_enable_crtc, -+ -+ .set_pixel_clock = bios_parser_set_pixel_clock, -+ -+ .set_dce_clock = bios_parser_set_dce_clock, -+ -+ .program_crtc_timing = bios_parser_program_crtc_timing, -+ -+ /* .blank_crtc = bios_parser_blank_crtc, */ -+ -+ .crtc_source_select = bios_parser_crtc_source_select, -+ -+ /* .external_encoder_control = bios_parser_external_encoder_control, */ -+ -+ .enable_disp_power_gating = bios_parser_enable_disp_power_gating, -+ -+ .post_init = bios_parser_post_init, -+ -+ .bios_parser_destroy = firmware_parser_destroy, -+ -+ .get_smu_clock_info = bios_parser_get_smu_clock_info, -+}; -+ -+static bool bios_parser_construct( -+ struct bios_parser *bp, -+ struct bp_init_data *init, -+ enum dce_version dce_version) -+{ -+ uint16_t *rom_header_offset = NULL; -+ struct atom_rom_header_v2_2 *rom_header = NULL; -+ struct display_object_info_table_v1_4 *object_info_tbl; -+ struct atom_data_revision tbl_rev = {0}; -+ -+ if (!init) -+ return false; -+ -+ if (!init->bios) -+ return false; -+ -+ bp->base.funcs = &vbios_funcs; -+ bp->base.bios = init->bios; -+ bp->base.bios_size = bp->base.bios[OFFSET_TO_ATOM_ROM_IMAGE_SIZE] * BIOS_IMAGE_SIZE_UNIT; -+ -+ bp->base.ctx = init->ctx; -+ -+ bp->base.bios_local_image = NULL; -+ -+ rom_header_offset = -+ GET_IMAGE(uint16_t, OFFSET_TO_ATOM_ROM_HEADER_POINTER); -+ -+ if (!rom_header_offset) -+ return false; -+ -+ rom_header = GET_IMAGE(struct atom_rom_header_v2_2, *rom_header_offset); -+ -+ if (!rom_header) -+ return false; -+ -+ get_atom_data_table_revision(&rom_header->table_header, &tbl_rev); -+ if (!(tbl_rev.major >= 2 && tbl_rev.minor >= 2)) -+ return false; -+ -+ bp->master_data_tbl = -+ GET_IMAGE(struct atom_master_data_table_v2_1, -+ rom_header->masterdatatable_offset); -+ -+ if (!bp->master_data_tbl) -+ return false; -+ -+ bp->object_info_tbl_offset = DATA_TABLES(displayobjectinfo); -+ -+ if (!bp->object_info_tbl_offset) -+ return false; -+ -+ object_info_tbl = -+ GET_IMAGE(struct display_object_info_table_v1_4, -+ bp->object_info_tbl_offset); -+ -+ if (!object_info_tbl) -+ return false; -+ -+ get_atom_data_table_revision(&object_info_tbl->table_header, -+ &bp->object_info_tbl.revision); -+ -+ if (bp->object_info_tbl.revision.major == 1 -+ && bp->object_info_tbl.revision.minor >= 4) { -+ struct display_object_info_table_v1_4 *tbl_v1_4; -+ -+ tbl_v1_4 = GET_IMAGE(struct display_object_info_table_v1_4, -+ bp->object_info_tbl_offset); -+ if (!tbl_v1_4) -+ return false; -+ -+ bp->object_info_tbl.v1_4 = tbl_v1_4; -+ } else -+ return false; -+ -+ dal_firmware_parser_init_cmd_tbl(bp); -+ dal_bios_parser_init_cmd_tbl_helper2(&bp->cmd_helper, dce_version); -+ -+ bp->base.integrated_info = bios_parser_create_integrated_info(&bp->base); -+ -+ return true; -+} -+ -+struct dc_bios *firmware_parser_create( -+ struct bp_init_data *init, -+ enum dce_version dce_version) -+{ -+ struct bios_parser *bp = NULL; -+ -+ bp = dm_alloc(sizeof(struct bios_parser)); -+ if (!bp) -+ return NULL; -+ -+ if (bios_parser_construct(bp, init, dce_version)) -+ return &bp->base; -+ -+ dm_free(bp); -+ return NULL; -+} -+ -+ -diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.h b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.h -new file mode 100644 -index 0000000..cb40546 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.h -@@ -0,0 +1,33 @@ -+/* -+ * Copyright 2012-15 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#ifndef __DAL_BIOS_PARSER2_H__ -+#define __DAL_BIOS_PARSER2_H__ -+ -+struct dc_bios *firmware_parser_create( -+ struct bp_init_data *init, -+ enum dce_version dce_version); -+ -+#endif -diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser_types_internal2.h b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_types_internal2.h -new file mode 100644 -index 0000000..bf1f5c8 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser_types_internal2.h -@@ -0,0 +1,74 @@ -+/* -+ * Copyright 2012-15 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#ifndef __DAL_BIOS_PARSER_TYPES_BIOS2_H__ -+#define __DAL_BIOS_PARSER_TYPES_BIOS2_H__ -+ -+#include "dc_bios_types.h" -+#include "bios_parser_helper.h" -+ -+/* use atomfirmware_bringup.h only. Not atombios.h anymore */ -+ -+struct atom_data_revision { -+ uint32_t major; -+ uint32_t minor; -+}; -+ -+struct object_info_table { -+ struct atom_data_revision revision; -+ union { -+ struct display_object_info_table_v1_4 *v1_4; -+ }; -+}; -+ -+enum spread_spectrum_id { -+ SS_ID_UNKNOWN = 0, -+ SS_ID_DP1 = 0xf1, -+ SS_ID_DP2 = 0xf2, -+ SS_ID_LVLINK_2700MHZ = 0xf3, -+ SS_ID_LVLINK_1620MHZ = 0xf4 -+}; -+ -+struct bios_parser { -+ struct dc_bios base; -+ -+ struct object_info_table object_info_tbl; -+ uint32_t object_info_tbl_offset; -+ struct atom_master_data_table_v2_1 *master_data_tbl; -+ -+ -+ const struct bios_parser_helper *bios_helper; -+ -+ const struct command_table_helper *cmd_helper; -+ struct cmd_tbl cmd_tbl; -+ -+ bool remap_device_tags; -+}; -+ -+/* Bios Parser from DC Bios */ -+#define BP_FROM_DCB(dc_bios) \ -+ container_of(dc_bios, struct bios_parser, base) -+ -+#endif -diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c -new file mode 100644 -index 0000000..36d1582 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.c -@@ -0,0 +1,813 @@ -+/* -+ * Copyright 2012-15 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#include "dm_services.h" -+ -+#include "ObjectID.h" -+#include "atomfirmware.h" -+#include "atomfirmwareid.h" -+ -+#include "include/bios_parser_interface.h" -+ -+#include "command_table2.h" -+#include "command_table_helper2.h" -+#include "bios_parser_helper.h" -+#include "bios_parser_types_internal2.h" -+ -+#define GET_INDEX_INTO_MASTER_TABLE(MasterOrData, FieldName)\ -+ (((char *)(&((\ -+ struct atom_master_list_of_##MasterOrData##_functions_v2_1 *)0)\ -+ ->FieldName)-(char *)0)/sizeof(uint16_t)) -+ -+#define EXEC_BIOS_CMD_TABLE(fname, params)\ -+ (cgs_atom_exec_cmd_table(bp->base.ctx->cgs_device, \ -+ GET_INDEX_INTO_MASTER_TABLE(command, fname), \ -+ ¶ms) == 0) -+ -+#define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\ -+ cgs_atom_get_cmd_table_revs(bp->base.ctx->cgs_device, \ -+ GET_INDEX_INTO_MASTER_TABLE(command, fname), &frev, &crev) -+ -+#define BIOS_CMD_TABLE_PARA_REVISION(fname)\ -+ bios_cmd_table_para_revision(bp->base.ctx->cgs_device, \ -+ GET_INDEX_INTO_MASTER_TABLE(command, fname)) -+ -+static void init_dig_encoder_control(struct bios_parser *bp); -+static void init_transmitter_control(struct bios_parser *bp); -+static void init_set_pixel_clock(struct bios_parser *bp); -+ -+static void init_set_crtc_timing(struct bios_parser *bp); -+ -+static void init_select_crtc_source(struct bios_parser *bp); -+static void init_enable_crtc(struct bios_parser *bp); -+ -+static void init_external_encoder_control(struct bios_parser *bp); -+static void init_enable_disp_power_gating(struct bios_parser *bp); -+static void init_set_dce_clock(struct bios_parser *bp); -+static void init_get_smu_clock_info(struct bios_parser *bp); -+ -+void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp) -+{ -+ init_dig_encoder_control(bp); -+ init_transmitter_control(bp); -+ init_set_pixel_clock(bp); -+ -+ init_set_crtc_timing(bp); -+ -+ init_select_crtc_source(bp); -+ init_enable_crtc(bp); -+ -+ init_external_encoder_control(bp); -+ init_enable_disp_power_gating(bp); -+ init_set_dce_clock(bp); -+ init_get_smu_clock_info(bp); -+} -+ -+static uint32_t bios_cmd_table_para_revision(void *cgs_device, -+ uint32_t index) -+{ -+ uint8_t frev, crev; -+ -+ if (cgs_atom_get_cmd_table_revs(cgs_device, -+ index, -+ &frev, &crev) != 0) -+ return 0; -+ return crev; -+} -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** D I G E N C O D E R C O N T R O L -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+static enum bp_result encoder_control_digx_v1_5( -+ struct bios_parser *bp, -+ struct bp_encoder_control *cntl); -+ -+static void init_dig_encoder_control(struct bios_parser *bp) -+{ -+ uint32_t version = -+ BIOS_CMD_TABLE_PARA_REVISION(digxencodercontrol); -+ -+ switch (version) { -+ case 5: -+ bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v1_5; -+ break; -+ default: -+ bp->cmd_tbl.dig_encoder_control = NULL; -+ break; -+ } -+} -+ -+static enum bp_result encoder_control_digx_v1_5( -+ struct bios_parser *bp, -+ struct bp_encoder_control *cntl) -+{ -+ enum bp_result result = BP_RESULT_FAILURE; -+ struct dig_encoder_stream_setup_parameters_v1_5 params = {0}; -+ -+ params.digid = (uint8_t)(cntl->engine_id); -+ params.action = bp->cmd_helper->encoder_action_to_atom(cntl->action); -+ -+ params.pclk_10khz = cntl->pixel_clock / 10; -+ params.digmode = -+ (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom( -+ cntl->signal, -+ cntl->enable_dp_audio)); -+ params.lanenum = (uint8_t)(cntl->lanes_number); -+ -+ switch (cntl->color_depth) { -+ case COLOR_DEPTH_888: -+ params.bitpercolor = PANEL_8BIT_PER_COLOR; -+ break; -+ case COLOR_DEPTH_101010: -+ params.bitpercolor = PANEL_10BIT_PER_COLOR; -+ break; -+ case COLOR_DEPTH_121212: -+ params.bitpercolor = PANEL_12BIT_PER_COLOR; -+ break; -+ case COLOR_DEPTH_161616: -+ params.bitpercolor = PANEL_16BIT_PER_COLOR; -+ break; -+ default: -+ break; -+ } -+ -+ if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A) -+ switch (cntl->color_depth) { -+ case COLOR_DEPTH_101010: -+ params.pclk_10khz = -+ (params.pclk_10khz * 30) / 24; -+ break; -+ case COLOR_DEPTH_121212: -+ params.pclk_10khz = -+ (params.pclk_10khz * 36) / 24; -+ break; -+ case COLOR_DEPTH_161616: -+ params.pclk_10khz = -+ (params.pclk_10khz * 48) / 24; -+ break; -+ default: -+ break; -+ } -+ -+ if (EXEC_BIOS_CMD_TABLE(digxencodercontrol, params)) -+ result = BP_RESULT_OK; -+ -+ return result; -+} -+ -+/***************************************************************************** -+ ****************************************************************************** -+ ** -+ ** TRANSMITTER CONTROL -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+static enum bp_result transmitter_control_v1_6( -+ struct bios_parser *bp, -+ struct bp_transmitter_control *cntl); -+ -+static void init_transmitter_control(struct bios_parser *bp) -+{ -+ uint8_t frev; -+ uint8_t crev; -+ -+ if (BIOS_CMD_TABLE_REVISION(dig1transmittercontrol, frev, crev) != 0) -+ BREAK_TO_DEBUGGER(); -+ switch (crev) { -+ case 6: -+ bp->cmd_tbl.transmitter_control = transmitter_control_v1_6; -+ break; -+ default: -+ bp->cmd_tbl.transmitter_control = NULL; -+ break; -+ } -+} -+ -+static enum bp_result transmitter_control_v1_6( -+ struct bios_parser *bp, -+ struct bp_transmitter_control *cntl) -+{ -+ enum bp_result result = BP_RESULT_FAILURE; -+ const struct command_table_helper *cmd = bp->cmd_helper; -+ struct dig_transmitter_control_ps_allocation_v1_6 ps = { { 0 } }; -+ -+ ps.param.phyid = cmd->phy_id_to_atom(cntl->transmitter); -+ ps.param.action = (uint8_t)cntl->action; -+ -+ if (cntl->action == TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS) -+ ps.param.mode_laneset.dplaneset = (uint8_t)cntl->lane_settings; -+ else -+ ps.param.mode_laneset.digmode = -+ cmd->signal_type_to_atom_dig_mode(cntl->signal); -+ -+ ps.param.lanenum = (uint8_t)cntl->lanes_number; -+ ps.param.hpdsel = cmd->hpd_sel_to_atom(cntl->hpd_sel); -+ ps.param.digfe_sel = cmd->dig_encoder_sel_to_atom(cntl->engine_id); -+ ps.param.connobj_id = (uint8_t)cntl->connector_obj_id.id; -+ ps.param.symclk_10khz = cntl->pixel_clock/10; -+ -+ -+ if (cntl->action == TRANSMITTER_CONTROL_ENABLE || -+ cntl->action == TRANSMITTER_CONTROL_ACTIAVATE || -+ cntl->action == TRANSMITTER_CONTROL_DEACTIVATE) { -+ dm_logger_write(bp->base.ctx->logger, LOG_HW_SET_MODE,\ -+ "************************%s:ps.param.symclk_10khz = %d\n",\ -+ __func__, ps.param.symclk_10khz); -+ } -+ -+ -+/*color_depth not used any more, driver has deep color factor in the Phyclk*/ -+ if (EXEC_BIOS_CMD_TABLE(dig1transmittercontrol, ps)) -+ result = BP_RESULT_OK; -+ return result; -+} -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** SET PIXEL CLOCK -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+static enum bp_result set_pixel_clock_v7( -+ struct bios_parser *bp, -+ struct bp_pixel_clock_parameters *bp_params); -+ -+static void init_set_pixel_clock(struct bios_parser *bp) -+{ -+ switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) { -+ case 7: -+ bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v7; -+ break; -+ default: -+ bp->cmd_tbl.set_pixel_clock = NULL; -+ break; -+ } -+} -+ -+ -+ -+static enum bp_result set_pixel_clock_v7( -+ struct bios_parser *bp, -+ struct bp_pixel_clock_parameters *bp_params) -+{ -+ enum bp_result result = BP_RESULT_FAILURE; -+ struct set_pixel_clock_parameter_v1_7 clk; -+ uint8_t controller_id; -+ uint32_t pll_id; -+ -+ memset(&clk, 0, sizeof(clk)); -+ -+ if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id) -+ && bp->cmd_helper->controller_id_to_atom(bp_params-> -+ controller_id, &controller_id)) { -+ /* Note: VBIOS still wants to use ucCRTC name which is now -+ * 1 byte in ULONG -+ *typedef struct _CRTC_PIXEL_CLOCK_FREQ -+ *{ -+ * target the pixel clock to drive the CRTC timing. -+ * ULONG ulPixelClock:24; -+ * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to -+ * previous version. -+ * ATOM_CRTC1~6, indicate the CRTC controller to -+ * ULONG ucCRTC:8; -+ * drive the pixel clock. not used for DCPLL case. -+ *}CRTC_PIXEL_CLOCK_FREQ; -+ *union -+ *{ -+ * pixel clock and CRTC id frequency -+ * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; -+ * ULONG ulDispEngClkFreq; dispclk frequency -+ *}; -+ */ -+ clk.crtc_id = controller_id; -+ clk.pll_id = (uint8_t) pll_id; -+ clk.encoderobjid = -+ bp->cmd_helper->encoder_id_to_atom( -+ dal_graphics_object_id_get_encoder_id( -+ bp_params->encoder_object_id)); -+ -+ clk.encoder_mode = (uint8_t) bp-> -+ cmd_helper->encoder_mode_bp_to_atom( -+ bp_params->signal_type, false); -+ -+ /* We need to convert from KHz units into 10KHz units */ -+ clk.pixclk_100hz = cpu_to_le32(bp_params->target_pixel_clock * -+ 10); -+ -+ clk.deep_color_ratio = -+ (uint8_t) bp->cmd_helper-> -+ transmitter_color_depth_to_atom( -+ bp_params->color_depth); -+ dm_logger_write(bp->base.ctx->logger, LOG_HW_SET_MODE,\ -+ "************************%s:program display clock = %d"\ -+ "colorDepth = %d\n", __func__,\ -+ bp_params->target_pixel_clock, bp_params->color_depth); -+ -+ if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) -+ clk.miscinfo |= PIXEL_CLOCK_V7_MISC_FORCE_PROG_PPLL; -+ -+ if (bp_params->flags.PROGRAM_PHY_PLL_ONLY) -+ clk.miscinfo |= PIXEL_CLOCK_V7_MISC_PROG_PHYPLL; -+ -+ if (bp_params->flags.SUPPORT_YUV_420) -+ clk.miscinfo |= PIXEL_CLOCK_V7_MISC_YUV420_MODE; -+ -+ if (bp_params->flags.SET_XTALIN_REF_SRC) -+ clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_XTALIN; -+ -+ if (bp_params->flags.SET_GENLOCK_REF_DIV_SRC) -+ clk.miscinfo |= PIXEL_CLOCK_V7_MISC_REF_DIV_SRC_GENLK; -+ -+ if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK) -+ clk.miscinfo |= PIXEL_CLOCK_V7_MISC_DVI_DUALLINK_EN; -+ -+ if (EXEC_BIOS_CMD_TABLE(setpixelclock, clk)) -+ result = BP_RESULT_OK; -+ } -+ return result; -+} -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** SET CRTC TIMING -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+static enum bp_result set_crtc_using_dtd_timing_v3( -+ struct bios_parser *bp, -+ struct bp_hw_crtc_timing_parameters *bp_params); -+ -+static void init_set_crtc_timing(struct bios_parser *bp) -+{ -+ uint32_t dtd_version = -+ BIOS_CMD_TABLE_PARA_REVISION(setcrtc_usingdtdtiming); -+ -+ switch (dtd_version) { -+ case 3: -+ bp->cmd_tbl.set_crtc_timing = -+ set_crtc_using_dtd_timing_v3; -+ break; -+ default: -+ bp->cmd_tbl.set_crtc_timing = NULL; -+ break; -+ } -+} -+ -+static enum bp_result set_crtc_using_dtd_timing_v3( -+ struct bios_parser *bp, -+ struct bp_hw_crtc_timing_parameters *bp_params) -+{ -+ enum bp_result result = BP_RESULT_FAILURE; -+ struct set_crtc_using_dtd_timing_parameters params = {0}; -+ uint8_t atom_controller_id; -+ -+ if (bp->cmd_helper->controller_id_to_atom( -+ bp_params->controller_id, &atom_controller_id)) -+ params.crtc_id = atom_controller_id; -+ -+ /* bios usH_Size wants h addressable size */ -+ params.h_size = cpu_to_le16((uint16_t)bp_params->h_addressable); -+ /* bios usH_Blanking_Time wants borders included in blanking */ -+ params.h_blanking_time = -+ cpu_to_le16((uint16_t)(bp_params->h_total - -+ bp_params->h_addressable)); -+ /* bios usV_Size wants v addressable size */ -+ params.v_size = cpu_to_le16((uint16_t)bp_params->v_addressable); -+ /* bios usV_Blanking_Time wants borders included in blanking */ -+ params.v_blanking_time = -+ cpu_to_le16((uint16_t)(bp_params->v_total - -+ bp_params->v_addressable)); -+ /* bios usHSyncOffset is the offset from the end of h addressable, -+ * our horizontalSyncStart is the offset from the beginning -+ * of h addressable -+ */ -+ params.h_syncoffset = -+ cpu_to_le16((uint16_t)(bp_params->h_sync_start - -+ bp_params->h_addressable)); -+ params.h_syncwidth = cpu_to_le16((uint16_t)bp_params->h_sync_width); -+ /* bios usHSyncOffset is the offset from the end of v addressable, -+ * our verticalSyncStart is the offset from the beginning of -+ * v addressable -+ */ -+ params.v_syncoffset = -+ cpu_to_le16((uint16_t)(bp_params->v_sync_start - -+ bp_params->v_addressable)); -+ params.v_syncwidth = cpu_to_le16((uint16_t)bp_params->v_sync_width); -+ -+ /* we assume that overscan from original timing does not get bigger -+ * than 255 -+ * we will program all the borders in the Set CRTC Overscan call below -+ */ -+ -+ if (bp_params->flags.HSYNC_POSITIVE_POLARITY == 0) -+ params.modemiscinfo = -+ cpu_to_le16(le16_to_cpu(params.modemiscinfo) | -+ ATOM_HSYNC_POLARITY); -+ -+ if (bp_params->flags.VSYNC_POSITIVE_POLARITY == 0) -+ params.modemiscinfo = -+ cpu_to_le16(le16_to_cpu(params.modemiscinfo) | -+ ATOM_VSYNC_POLARITY); -+ -+ if (bp_params->flags.INTERLACE) { -+ params.modemiscinfo = -+ cpu_to_le16(le16_to_cpu(params.modemiscinfo) | -+ ATOM_INTERLACE); -+ -+ /* original DAL code has this condition to apply this -+ * for non-TV/CV only -+ * due to complex MV testing for possible impact -+ * if ( pACParameters->signal != SignalType_YPbPr && -+ * pACParameters->signal != SignalType_Composite && -+ * pACParameters->signal != SignalType_SVideo) -+ */ -+ { -+ /* HW will deduct 0.5 line from 2nd feild. -+ * i.e. for 1080i, it is 2 lines for 1st field, -+ * 2.5 lines for the 2nd feild. we need input as 5 -+ * instead of 4. -+ * but it is 4 either from Edid data (spec CEA 861) -+ * or CEA timing table. -+ */ -+ params.v_syncoffset = -+ cpu_to_le16(le16_to_cpu(params.v_syncoffset) + -+ 1); -+ -+ } -+ } -+ -+ if (bp_params->flags.HORZ_COUNT_BY_TWO) -+ params.modemiscinfo = -+ cpu_to_le16(le16_to_cpu(params.modemiscinfo) | -+ 0x100); /* ATOM_DOUBLE_CLOCK_MODE */ -+ -+ if (EXEC_BIOS_CMD_TABLE(setcrtc_usingdtdtiming, params)) -+ result = BP_RESULT_OK; -+ -+ return result; -+} -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** SELECT CRTC SOURCE -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+ -+static enum bp_result select_crtc_source_v3( -+ struct bios_parser *bp, -+ struct bp_crtc_source_select *bp_params); -+ -+static void init_select_crtc_source(struct bios_parser *bp) -+{ -+ switch (BIOS_CMD_TABLE_PARA_REVISION(selectcrtc_source)) { -+ case 3: -+ bp->cmd_tbl.select_crtc_source = select_crtc_source_v3; -+ break; -+ default: -+ bp->cmd_tbl.select_crtc_source = NULL; -+ break; -+ } -+} -+ -+ -+static enum bp_result select_crtc_source_v3( -+ struct bios_parser *bp, -+ struct bp_crtc_source_select *bp_params) -+{ -+ bool result = BP_RESULT_FAILURE; -+ struct select_crtc_source_parameters_v2_3 params; -+ uint8_t atom_controller_id; -+ uint32_t atom_engine_id; -+ enum signal_type s = bp_params->signal; -+ -+ memset(¶ms, 0, sizeof(params)); -+ -+ if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id, -+ &atom_controller_id)) -+ params.crtc_id = atom_controller_id; -+ else -+ return result; -+ -+ if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id, -+ &atom_engine_id)) -+ params.encoder_id = (uint8_t)atom_engine_id; -+ else -+ return result; -+ -+ if (s == SIGNAL_TYPE_EDP || -+ (s == SIGNAL_TYPE_DISPLAY_PORT && bp_params->sink_signal == -+ SIGNAL_TYPE_LVDS)) -+ s = SIGNAL_TYPE_LVDS; -+ -+ params.encode_mode = -+ bp->cmd_helper->encoder_mode_bp_to_atom( -+ s, bp_params->enable_dp_audio); -+ /* Needed for VBIOS Random Spatial Dithering feature */ -+ params.dst_bpc = (uint8_t)(bp_params->display_output_bit_depth); -+ -+ if (EXEC_BIOS_CMD_TABLE(selectcrtc_source, params)) -+ result = BP_RESULT_OK; -+ -+ return result; -+} -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** ENABLE CRTC -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+static enum bp_result enable_crtc_v1( -+ struct bios_parser *bp, -+ enum controller_id controller_id, -+ bool enable); -+ -+static void init_enable_crtc(struct bios_parser *bp) -+{ -+ switch (BIOS_CMD_TABLE_PARA_REVISION(enablecrtc)) { -+ case 1: -+ bp->cmd_tbl.enable_crtc = enable_crtc_v1; -+ break; -+ default: -+ bp->cmd_tbl.enable_crtc = NULL; -+ break; -+ } -+} -+ -+static enum bp_result enable_crtc_v1( -+ struct bios_parser *bp, -+ enum controller_id controller_id, -+ bool enable) -+{ -+ bool result = BP_RESULT_FAILURE; -+ struct enable_crtc_parameters params = {0}; -+ uint8_t id; -+ -+ if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) -+ params.crtc_id = id; -+ else -+ return BP_RESULT_BADINPUT; -+ -+ if (enable) -+ params.enable = ATOM_ENABLE; -+ else -+ params.enable = ATOM_DISABLE; -+ -+ if (EXEC_BIOS_CMD_TABLE(enablecrtc, params)) -+ result = BP_RESULT_OK; -+ -+ return result; -+} -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** DISPLAY PLL -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+ -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** EXTERNAL ENCODER CONTROL -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+static enum bp_result external_encoder_control_v3( -+ struct bios_parser *bp, -+ struct bp_external_encoder_control *cntl); -+ -+static void init_external_encoder_control( -+ struct bios_parser *bp) -+{ -+ switch (BIOS_CMD_TABLE_PARA_REVISION(externalencodercontrol)) { -+ case 3: -+ bp->cmd_tbl.external_encoder_control = -+ external_encoder_control_v3; -+ break; -+ default: -+ bp->cmd_tbl.external_encoder_control = NULL; -+ break; -+ } -+} -+ -+static enum bp_result external_encoder_control_v3( -+ struct bios_parser *bp, -+ struct bp_external_encoder_control *cntl) -+{ -+ /* TODO */ -+ return BP_RESULT_OK; -+} -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** ENABLE DISPLAY POWER GATING -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+static enum bp_result enable_disp_power_gating_v2_1( -+ struct bios_parser *bp, -+ enum controller_id crtc_id, -+ enum bp_pipe_control_action action); -+ -+static void init_enable_disp_power_gating( -+ struct bios_parser *bp) -+{ -+ switch (BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating)) { -+ case 1: -+ bp->cmd_tbl.enable_disp_power_gating = -+ enable_disp_power_gating_v2_1; -+ break; -+ default: -+ bp->cmd_tbl.enable_disp_power_gating = NULL; -+ break; -+ } -+} -+ -+static enum bp_result enable_disp_power_gating_v2_1( -+ struct bios_parser *bp, -+ enum controller_id crtc_id, -+ enum bp_pipe_control_action action) -+{ -+ enum bp_result result = BP_RESULT_FAILURE; -+ -+ -+ struct enable_disp_power_gating_ps_allocation ps = { { 0 } }; -+ uint8_t atom_crtc_id; -+ -+ if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id)) -+ ps.param.disp_pipe_id = atom_crtc_id; -+ else -+ return BP_RESULT_BADINPUT; -+ -+ ps.param.enable = -+ bp->cmd_helper->disp_power_gating_action_to_atom(action); -+ -+ if (EXEC_BIOS_CMD_TABLE(enabledisppowergating, ps.param)) -+ result = BP_RESULT_OK; -+ -+ return result; -+} -+ -+/****************************************************************************** -+******************************************************************************* -+ ** -+ ** SET DCE CLOCK -+ ** -+******************************************************************************* -+*******************************************************************************/ -+ -+static enum bp_result set_dce_clock_v2_1( -+ struct bios_parser *bp, -+ struct bp_set_dce_clock_parameters *bp_params); -+ -+static void init_set_dce_clock(struct bios_parser *bp) -+{ -+ switch (BIOS_CMD_TABLE_PARA_REVISION(setdceclock)) { -+ case 1: -+ bp->cmd_tbl.set_dce_clock = set_dce_clock_v2_1; -+ break; -+ default: -+ bp->cmd_tbl.set_dce_clock = NULL; -+ break; -+ } -+} -+ -+static enum bp_result set_dce_clock_v2_1( -+ struct bios_parser *bp, -+ struct bp_set_dce_clock_parameters *bp_params) -+{ -+ enum bp_result result = BP_RESULT_FAILURE; -+ -+ struct set_dce_clock_ps_allocation_v2_1 params; -+ uint32_t atom_pll_id; -+ uint32_t atom_clock_type; -+ const struct command_table_helper *cmd = bp->cmd_helper; -+ -+ memset(¶ms, 0, sizeof(params)); -+ -+ if (!cmd->clock_source_id_to_atom(bp_params->pll_id, &atom_pll_id) || -+ !cmd->dc_clock_type_to_atom(bp_params->clock_type, -+ &atom_clock_type)) -+ return BP_RESULT_BADINPUT; -+ -+ params.param.dceclksrc = atom_pll_id; -+ params.param.dceclktype = atom_clock_type; -+ -+ if (bp_params->clock_type == DCECLOCK_TYPE_DPREFCLK) { -+ if (bp_params->flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK) -+ params.param.dceclkflag |= -+ DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENLK; -+ -+ if (bp_params->flags.USE_PCIE_AS_SOURCE_FOR_DPREFCLK) -+ params.param.dceclkflag |= -+ DCE_CLOCK_FLAG_PLL_REFCLK_SRC_PCIE; -+ -+ if (bp_params->flags.USE_XTALIN_AS_SOURCE_FOR_DPREFCLK) -+ params.param.dceclkflag |= -+ DCE_CLOCK_FLAG_PLL_REFCLK_SRC_XTALIN; -+ -+ if (bp_params->flags.USE_GENERICA_AS_SOURCE_FOR_DPREFCLK) -+ params.param.dceclkflag |= -+ DCE_CLOCK_FLAG_PLL_REFCLK_SRC_GENERICA; -+ } else -+ /* only program clock frequency if display clock is used; -+ * VBIOS will program DPREFCLK -+ * We need to convert from KHz units into 10KHz units -+ */ -+ params.param.dceclk_10khz = cpu_to_le32( -+ bp_params->target_clock_frequency / 10); -+ dm_logger_write(bp->base.ctx->logger, LOG_HW_SET_MODE, -+ "************************%s:target_clock_frequency = %d"\ -+ "clock_type = %d \n", __func__,\ -+ bp_params->target_clock_frequency,\ -+ bp_params->clock_type); -+ -+ if (EXEC_BIOS_CMD_TABLE(setdceclock, params)) { -+ /* Convert from 10KHz units back to KHz */ -+ bp_params->target_clock_frequency = le32_to_cpu( -+ params.param.dceclk_10khz) * 10; -+ result = BP_RESULT_OK; -+ } -+ -+ return result; -+} -+ -+ -+/****************************************************************************** -+ ****************************************************************************** -+ ** -+ ** GET SMU CLOCK INFO -+ ** -+ ****************************************************************************** -+ *****************************************************************************/ -+ -+static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp); -+ -+static void init_get_smu_clock_info(struct bios_parser *bp) -+{ -+ /* TODO add switch for table vrsion */ -+ bp->cmd_tbl.get_smu_clock_info = get_smu_clock_info_v3_1; -+ -+} -+ -+static unsigned int get_smu_clock_info_v3_1(struct bios_parser *bp) -+{ -+ struct atom_get_smu_clock_info_parameters_v3_1 smu_input = {0}; -+ struct atom_get_smu_clock_info_output_parameters_v3_1 smu_output; -+ -+ smu_input.command = GET_SMU_CLOCK_INFO_V3_1_GET_PLLVCO_FREQ; -+ -+ /* Get Specific Clock */ -+ if (EXEC_BIOS_CMD_TABLE(getsmuclockinfo, smu_input)) { -+ memmove(&smu_output, &smu_input, sizeof( -+ struct atom_get_smu_clock_info_parameters_v3_1)); -+ return smu_output.atom_smu_outputclkfreq.syspllvcofreq_10khz; -+ } -+ -+ return 0; -+} -+ -diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table2.h b/drivers/gpu/drm/amd/display/dc/bios/command_table2.h -new file mode 100644 -index 0000000..59061b8 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table2.h -@@ -0,0 +1,105 @@ -+/* -+ * Copyright 2012-15 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#ifndef __DAL_COMMAND_TABLE2_H__ -+#define __DAL_COMMAND_TABLE2_H__ -+ -+struct bios_parser; -+struct bp_encoder_control; -+ -+struct cmd_tbl { -+ enum bp_result (*dig_encoder_control)( -+ struct bios_parser *bp, -+ struct bp_encoder_control *control); -+ enum bp_result (*encoder_control_dig1)( -+ struct bios_parser *bp, -+ struct bp_encoder_control *control); -+ enum bp_result (*encoder_control_dig2)( -+ struct bios_parser *bp, -+ struct bp_encoder_control *control); -+ enum bp_result (*transmitter_control)( -+ struct bios_parser *bp, -+ struct bp_transmitter_control *control); -+ enum bp_result (*set_pixel_clock)( -+ struct bios_parser *bp, -+ struct bp_pixel_clock_parameters *bp_params); -+ enum bp_result (*enable_spread_spectrum_on_ppll)( -+ struct bios_parser *bp, -+ struct bp_spread_spectrum_parameters *bp_params, -+ bool enable); -+ enum bp_result (*adjust_display_pll)( -+ struct bios_parser *bp, -+ struct bp_adjust_pixel_clock_parameters *bp_params); -+ enum bp_result (*dac1_encoder_control)( -+ struct bios_parser *bp, -+ bool enable, -+ uint32_t pixel_clock, -+ uint8_t dac_standard); -+ enum bp_result (*dac2_encoder_control)( -+ struct bios_parser *bp, -+ bool enable, -+ uint32_t pixel_clock, -+ uint8_t dac_standard); -+ enum bp_result (*dac1_output_control)( -+ struct bios_parser *bp, -+ bool enable); -+ enum bp_result (*dac2_output_control)( -+ struct bios_parser *bp, -+ bool enable); -+ enum bp_result (*set_crtc_timing)( -+ struct bios_parser *bp, -+ struct bp_hw_crtc_timing_parameters *bp_params); -+ enum bp_result (*select_crtc_source)( -+ struct bios_parser *bp, -+ struct bp_crtc_source_select *bp_params); -+ enum bp_result (*enable_crtc)( -+ struct bios_parser *bp, -+ enum controller_id controller_id, -+ bool enable); -+ enum bp_result (*enable_crtc_mem_req)( -+ struct bios_parser *bp, -+ enum controller_id controller_id, -+ bool enable); -+ enum bp_result (*program_clock)( -+ struct bios_parser *bp, -+ struct bp_pixel_clock_parameters *bp_params); -+ enum bp_result (*external_encoder_control)( -+ struct bios_parser *bp, -+ struct bp_external_encoder_control *cntl); -+ enum bp_result (*enable_disp_power_gating)( -+ struct bios_parser *bp, -+ enum controller_id crtc_id, -+ enum bp_pipe_control_action action); -+ enum bp_result (*set_dce_clock)( -+ struct bios_parser *bp, -+ struct bp_set_dce_clock_parameters *bp_params); -+ unsigned int (*get_smu_clock_info)( -+ struct bios_parser *bp); -+ -+}; -+ -+void dal_firmware_parser_init_cmd_tbl(struct bios_parser *bp); -+ -+#endif -diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c -new file mode 100644 -index 0000000..b0dcad2 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.c -@@ -0,0 +1,260 @@ -+/* -+ * Copyright 2012-15 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#include "dm_services.h" -+ -+#include "ObjectID.h" -+#include "atomfirmware.h" -+#include "atomfirmwareid.h" -+ -+#include "include/bios_parser_types.h" -+ -+#include "command_table_helper2.h" -+ -+bool dal_bios_parser_init_cmd_tbl_helper2( -+ const struct command_table_helper **h, -+ enum dce_version dce) -+{ -+ switch (dce) { -+ case DCE_VERSION_8_0: -+ *h = dal_cmd_tbl_helper_dce80_get_table(); -+ return true; -+ -+ case DCE_VERSION_10_0: -+ *h = dal_cmd_tbl_helper_dce110_get_table(); -+ return true; -+ -+ case DCE_VERSION_11_0: -+ *h = dal_cmd_tbl_helper_dce110_get_table(); -+ return true; -+ -+ case DCE_VERSION_11_2: -+ *h = dal_cmd_tbl_helper_dce112_get_table2(); -+ return true; -+#if defined(CONFIG_DRM_AMD_DC_DCE12_0) -+ case DCE_VERSION_12_0: -+ *h = dal_cmd_tbl_helper_dce112_get_table2(); -+ return true; -+#endif -+ -+ default: -+ /* Unsupported DCE */ -+ BREAK_TO_DEBUGGER(); -+ return false; -+ } -+} -+ -+/* real implementations */ -+ -+bool dal_cmd_table_helper_controller_id_to_atom2( -+ enum controller_id id, -+ uint8_t *atom_id) -+{ -+ if (atom_id == NULL) { -+ BREAK_TO_DEBUGGER(); -+ return false; -+ } -+ -+ switch (id) { -+ case CONTROLLER_ID_D0: -+ *atom_id = ATOM_CRTC1; -+ return true; -+ case CONTROLLER_ID_D1: -+ *atom_id = ATOM_CRTC2; -+ return true; -+ case CONTROLLER_ID_D2: -+ *atom_id = ATOM_CRTC3; -+ return true; -+ case CONTROLLER_ID_D3: -+ *atom_id = ATOM_CRTC4; -+ return true; -+ case CONTROLLER_ID_D4: -+ *atom_id = ATOM_CRTC5; -+ return true; -+ case CONTROLLER_ID_D5: -+ *atom_id = ATOM_CRTC6; -+ return true; -+ /* TODO :case CONTROLLER_ID_UNDERLAY0: -+ *atom_id = ATOM_UNDERLAY_PIPE0; -+ return true; -+ */ -+ case CONTROLLER_ID_UNDEFINED: -+ *atom_id = ATOM_CRTC_INVALID; -+ return true; -+ default: -+ /* Wrong controller id */ -+ BREAK_TO_DEBUGGER(); -+ return false; -+ } -+} -+ -+/** -+* translate_transmitter_bp_to_atom -+* -+* @brief -+* Translate the Transmitter to the corresponding ATOM BIOS value -+* -+* @param -+* input transmitter -+* output digitalTransmitter -+* // =00: Digital Transmitter1 ( UNIPHY linkAB ) -+* // =01: Digital Transmitter2 ( UNIPHY linkCD ) -+* // =02: Digital Transmitter3 ( UNIPHY linkEF ) -+*/ -+uint8_t dal_cmd_table_helper_transmitter_bp_to_atom2( -+ enum transmitter t) -+{ -+ switch (t) { -+ case TRANSMITTER_UNIPHY_A: -+ case TRANSMITTER_UNIPHY_B: -+ case TRANSMITTER_TRAVIS_LCD: -+ return 0; -+ case TRANSMITTER_UNIPHY_C: -+ case TRANSMITTER_UNIPHY_D: -+ return 1; -+ case TRANSMITTER_UNIPHY_E: -+ case TRANSMITTER_UNIPHY_F: -+ return 2; -+ default: -+ /* Invalid Transmitter Type! */ -+ BREAK_TO_DEBUGGER(); -+ return 0; -+ } -+} -+ -+uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom2( -+ enum signal_type s, -+ bool enable_dp_audio) -+{ -+ switch (s) { -+ case SIGNAL_TYPE_DVI_SINGLE_LINK: -+ case SIGNAL_TYPE_DVI_DUAL_LINK: -+ return ATOM_ENCODER_MODE_DVI; -+ case SIGNAL_TYPE_HDMI_TYPE_A: -+ return ATOM_ENCODER_MODE_HDMI; -+ case SIGNAL_TYPE_LVDS: -+ return ATOM_ENCODER_MODE_LVDS; -+ case SIGNAL_TYPE_EDP: -+ case SIGNAL_TYPE_DISPLAY_PORT_MST: -+ case SIGNAL_TYPE_DISPLAY_PORT: -+ case SIGNAL_TYPE_VIRTUAL: -+ if (enable_dp_audio) -+ return ATOM_ENCODER_MODE_DP_AUDIO; -+ else -+ return ATOM_ENCODER_MODE_DP; -+ case SIGNAL_TYPE_RGB: -+ return ATOM_ENCODER_MODE_CRT; -+ default: -+ return ATOM_ENCODER_MODE_CRT; -+ } -+} -+ -+bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src2( -+ enum clock_source_id id, -+ uint32_t *ref_clk_src_id) -+{ -+ if (ref_clk_src_id == NULL) { -+ BREAK_TO_DEBUGGER(); -+ return false; -+ } -+ -+ switch (id) { -+ case CLOCK_SOURCE_ID_PLL1: -+ *ref_clk_src_id = ENCODER_REFCLK_SRC_P1PLL; -+ return true; -+ case CLOCK_SOURCE_ID_PLL2: -+ *ref_clk_src_id = ENCODER_REFCLK_SRC_P2PLL; -+ return true; -+ /*TODO:case CLOCK_SOURCE_ID_DCPLL: -+ *ref_clk_src_id = ENCODER_REFCLK_SRC_DCPLL; -+ return true; -+ */ -+ case CLOCK_SOURCE_ID_EXTERNAL: -+ *ref_clk_src_id = ENCODER_REFCLK_SRC_EXTCLK; -+ return true; -+ case CLOCK_SOURCE_ID_UNDEFINED: -+ *ref_clk_src_id = ENCODER_REFCLK_SRC_INVALID; -+ return true; -+ default: -+ /* Unsupported clock source id */ -+ BREAK_TO_DEBUGGER(); -+ return false; -+ } -+} -+ -+uint8_t dal_cmd_table_helper_encoder_id_to_atom2( -+ enum encoder_id id) -+{ -+ switch (id) { -+ case ENCODER_ID_INTERNAL_LVDS: -+ return ENCODER_OBJECT_ID_INTERNAL_LVDS; -+ case ENCODER_ID_INTERNAL_TMDS1: -+ return ENCODER_OBJECT_ID_INTERNAL_TMDS1; -+ case ENCODER_ID_INTERNAL_TMDS2: -+ return ENCODER_OBJECT_ID_INTERNAL_TMDS2; -+ case ENCODER_ID_INTERNAL_DAC1: -+ return ENCODER_OBJECT_ID_INTERNAL_DAC1; -+ case ENCODER_ID_INTERNAL_DAC2: -+ return ENCODER_OBJECT_ID_INTERNAL_DAC2; -+ case ENCODER_ID_INTERNAL_LVTM1: -+ return ENCODER_OBJECT_ID_INTERNAL_LVTM1; -+ case ENCODER_ID_INTERNAL_HDMI: -+ return ENCODER_OBJECT_ID_HDMI_INTERNAL; -+ case ENCODER_ID_EXTERNAL_TRAVIS: -+ return ENCODER_OBJECT_ID_TRAVIS; -+ case ENCODER_ID_EXTERNAL_NUTMEG: -+ return ENCODER_OBJECT_ID_NUTMEG; -+ case ENCODER_ID_INTERNAL_KLDSCP_TMDS1: -+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; -+ case ENCODER_ID_INTERNAL_KLDSCP_DAC1: -+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; -+ case ENCODER_ID_INTERNAL_KLDSCP_DAC2: -+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; -+ case ENCODER_ID_EXTERNAL_MVPU_FPGA: -+ return ENCODER_OBJECT_ID_MVPU_FPGA; -+ case ENCODER_ID_INTERNAL_DDI: -+ return ENCODER_OBJECT_ID_INTERNAL_DDI; -+ case ENCODER_ID_INTERNAL_UNIPHY: -+ return ENCODER_OBJECT_ID_INTERNAL_UNIPHY; -+ case ENCODER_ID_INTERNAL_KLDSCP_LVTMA: -+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA; -+ case ENCODER_ID_INTERNAL_UNIPHY1: -+ return ENCODER_OBJECT_ID_INTERNAL_UNIPHY1; -+ case ENCODER_ID_INTERNAL_UNIPHY2: -+ return ENCODER_OBJECT_ID_INTERNAL_UNIPHY2; -+ case ENCODER_ID_INTERNAL_UNIPHY3: -+ return ENCODER_OBJECT_ID_INTERNAL_UNIPHY3; -+ case ENCODER_ID_INTERNAL_WIRELESS: -+ return ENCODER_OBJECT_ID_INTERNAL_VCE; -+ case ENCODER_ID_INTERNAL_VIRTUAL: -+ return ENCODER_OBJECT_ID_NONE; -+ case ENCODER_ID_UNKNOWN: -+ return ENCODER_OBJECT_ID_NONE; -+ default: -+ /* Invalid encoder id */ -+ BREAK_TO_DEBUGGER(); -+ return ENCODER_OBJECT_ID_NONE; -+ } -+} -diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h -new file mode 100644 -index 0000000..9f587c9 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/bios/command_table_helper2.h -@@ -0,0 +1,82 @@ -+/* -+ * Copyright 2012-15 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#ifndef __DAL_COMMAND_TABLE_HELPER2_H__ -+#define __DAL_COMMAND_TABLE_HELPER2_H__ -+ -+#include "dce80/command_table_helper_dce80.h" -+#include "dce110/command_table_helper_dce110.h" -+#include "dce112/command_table_helper2_dce112.h" -+ -+struct command_table_helper { -+ bool (*controller_id_to_atom)(enum controller_id id, uint8_t *atom_id); -+ uint8_t (*encoder_action_to_atom)( -+ enum bp_encoder_control_action action); -+ uint32_t (*encoder_mode_bp_to_atom)(enum signal_type s, -+ bool enable_dp_audio); -+ bool (*engine_bp_to_atom)(enum engine_id engine_id, -+ uint32_t *atom_engine_id); -+ bool (*clock_source_id_to_atom)(enum clock_source_id id, -+ uint32_t *atom_pll_id); -+ bool (*clock_source_id_to_ref_clk_src)( -+ enum clock_source_id id, -+ uint32_t *ref_clk_src_id); -+ uint8_t (*transmitter_bp_to_atom)(enum transmitter t); -+ uint8_t (*encoder_id_to_atom)(enum encoder_id id); -+ uint8_t (*clock_source_id_to_atom_phy_clk_src_id)( -+ enum clock_source_id id); -+ uint8_t (*signal_type_to_atom_dig_mode)(enum signal_type s); -+ uint8_t (*hpd_sel_to_atom)(enum hpd_source_id id); -+ uint8_t (*dig_encoder_sel_to_atom)(enum engine_id engine_id); -+ uint8_t (*phy_id_to_atom)(enum transmitter t); -+ uint8_t (*disp_power_gating_action_to_atom)( -+ enum bp_pipe_control_action action); -+ bool (*dc_clock_type_to_atom)(enum bp_dce_clock_type id, -+ uint32_t *atom_clock_type); -+ uint8_t (*transmitter_color_depth_to_atom)( -+ enum transmitter_color_depth id); -+}; -+ -+bool dal_bios_parser_init_cmd_tbl_helper2(const struct command_table_helper **h, -+ enum dce_version dce); -+ -+bool dal_cmd_table_helper_controller_id_to_atom2( -+ enum controller_id id, -+ uint8_t *atom_id); -+ -+uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom2( -+ enum signal_type s, -+ bool enable_dp_audio); -+ -+bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src2( -+ enum clock_source_id id, -+ uint32_t *ref_clk_src_id); -+ -+uint8_t dal_cmd_table_helper_transmitter_bp_to_atom2( -+ enum transmitter t); -+ -+uint8_t dal_cmd_table_helper_encoder_id_to_atom2( -+ enum encoder_id id); -+#endif -diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c -new file mode 100644 -index 0000000..d342cde ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.c -@@ -0,0 +1,418 @@ -+/* -+ * Copyright 2012-15 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#include "dm_services.h" -+ -+#include "atom.h" -+ -+#include "include/bios_parser_types.h" -+ -+#include "../command_table_helper2.h" -+ -+static uint8_t phy_id_to_atom(enum transmitter t) -+{ -+ uint8_t atom_phy_id; -+ -+ switch (t) { -+ case TRANSMITTER_UNIPHY_A: -+ atom_phy_id = ATOM_PHY_ID_UNIPHYA; -+ break; -+ case TRANSMITTER_UNIPHY_B: -+ atom_phy_id = ATOM_PHY_ID_UNIPHYB; -+ break; -+ case TRANSMITTER_UNIPHY_C: -+ atom_phy_id = ATOM_PHY_ID_UNIPHYC; -+ break; -+ case TRANSMITTER_UNIPHY_D: -+ atom_phy_id = ATOM_PHY_ID_UNIPHYD; -+ break; -+ case TRANSMITTER_UNIPHY_E: -+ atom_phy_id = ATOM_PHY_ID_UNIPHYE; -+ break; -+ case TRANSMITTER_UNIPHY_F: -+ atom_phy_id = ATOM_PHY_ID_UNIPHYF; -+ break; -+ case TRANSMITTER_UNIPHY_G: -+ atom_phy_id = ATOM_PHY_ID_UNIPHYG; -+ break; -+ default: -+ atom_phy_id = ATOM_PHY_ID_UNIPHYA; -+ break; -+ } -+ return atom_phy_id; -+} -+ -+static uint8_t signal_type_to_atom_dig_mode(enum signal_type s) -+{ -+ uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP; -+ -+ switch (s) { -+ case SIGNAL_TYPE_DISPLAY_PORT: -+ case SIGNAL_TYPE_EDP: -+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP; -+ break; -+ case SIGNAL_TYPE_DVI_SINGLE_LINK: -+ case SIGNAL_TYPE_DVI_DUAL_LINK: -+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI; -+ break; -+ case SIGNAL_TYPE_HDMI_TYPE_A: -+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_HDMI; -+ break; -+ case SIGNAL_TYPE_DISPLAY_PORT_MST: -+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP_MST; -+ break; -+ default: -+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI; -+ break; -+ } -+ -+ return atom_dig_mode; -+} -+ -+static uint8_t clock_source_id_to_atom_phy_clk_src_id( -+ enum clock_source_id id) -+{ -+ uint8_t atom_phy_clk_src_id = 0; -+ -+ switch (id) { -+ case CLOCK_SOURCE_ID_PLL0: -+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL; -+ break; -+ case CLOCK_SOURCE_ID_PLL1: -+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; -+ break; -+ case CLOCK_SOURCE_ID_PLL2: -+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL; -+ break; -+ case CLOCK_SOURCE_ID_EXTERNAL: -+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT; -+ break; -+ default: -+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL; -+ break; -+ } -+ -+ return atom_phy_clk_src_id >> 2; -+} -+ -+static uint8_t hpd_sel_to_atom(enum hpd_source_id id) -+{ -+ uint8_t atom_hpd_sel = 0; -+ -+ switch (id) { -+ case HPD_SOURCEID1: -+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD1_SEL; -+ break; -+ case HPD_SOURCEID2: -+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD2_SEL; -+ break; -+ case HPD_SOURCEID3: -+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD3_SEL; -+ break; -+ case HPD_SOURCEID4: -+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD4_SEL; -+ break; -+ case HPD_SOURCEID5: -+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD5_SEL; -+ break; -+ case HPD_SOURCEID6: -+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD6_SEL; -+ break; -+ case HPD_SOURCEID_UNKNOWN: -+ default: -+ atom_hpd_sel = 0; -+ break; -+ } -+ return atom_hpd_sel; -+} -+ -+static uint8_t dig_encoder_sel_to_atom(enum engine_id id) -+{ -+ uint8_t atom_dig_encoder_sel = 0; -+ -+ switch (id) { -+ case ENGINE_ID_DIGA: -+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGA_SEL; -+ break; -+ case ENGINE_ID_DIGB: -+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGB_SEL; -+ break; -+ case ENGINE_ID_DIGC: -+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGC_SEL; -+ break; -+ case ENGINE_ID_DIGD: -+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGD_SEL; -+ break; -+ case ENGINE_ID_DIGE: -+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGE_SEL; -+ break; -+ case ENGINE_ID_DIGF: -+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGF_SEL; -+ break; -+ case ENGINE_ID_DIGG: -+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGG_SEL; -+ break; -+ case ENGINE_ID_UNKNOWN: -+ /* No DIG_FRONT is associated to DIG_BACKEND */ -+ atom_dig_encoder_sel = 0; -+ break; -+ default: -+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGA_SEL; -+ break; -+ } -+ -+ return 0; -+} -+ -+static bool clock_source_id_to_atom( -+ enum clock_source_id id, -+ uint32_t *atom_pll_id) -+{ -+ bool result = true; -+ -+ if (atom_pll_id != NULL) -+ switch (id) { -+ case CLOCK_SOURCE_COMBO_PHY_PLL0: -+ *atom_pll_id = ATOM_COMBOPHY_PLL0; -+ break; -+ case CLOCK_SOURCE_COMBO_PHY_PLL1: -+ *atom_pll_id = ATOM_COMBOPHY_PLL1; -+ break; -+ case CLOCK_SOURCE_COMBO_PHY_PLL2: -+ *atom_pll_id = ATOM_COMBOPHY_PLL2; -+ break; -+ case CLOCK_SOURCE_COMBO_PHY_PLL3: -+ *atom_pll_id = ATOM_COMBOPHY_PLL3; -+ break; -+ case CLOCK_SOURCE_COMBO_PHY_PLL4: -+ *atom_pll_id = ATOM_COMBOPHY_PLL4; -+ break; -+ case CLOCK_SOURCE_COMBO_PHY_PLL5: -+ *atom_pll_id = ATOM_COMBOPHY_PLL5; -+ break; -+ case CLOCK_SOURCE_COMBO_DISPLAY_PLL0: -+ *atom_pll_id = ATOM_PPLL0; -+ break; -+ case CLOCK_SOURCE_ID_DFS: -+ *atom_pll_id = ATOM_GCK_DFS; -+ break; -+ case CLOCK_SOURCE_ID_VCE: -+ *atom_pll_id = ATOM_DP_DTO; -+ break; -+ case CLOCK_SOURCE_ID_DP_DTO: -+ *atom_pll_id = ATOM_DP_DTO; -+ break; -+ case CLOCK_SOURCE_ID_UNDEFINED: -+ /* Should not happen */ -+ *atom_pll_id = ATOM_PPLL_INVALID; -+ result = false; -+ break; -+ default: -+ result = false; -+ break; -+ } -+ -+ return result; -+} -+ -+static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id) -+{ -+ bool result = false; -+ -+ if (atom_engine_id != NULL) -+ switch (id) { -+ case ENGINE_ID_DIGA: -+ *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID; -+ result = true; -+ break; -+ case ENGINE_ID_DIGB: -+ *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID; -+ result = true; -+ break; -+ case ENGINE_ID_DIGC: -+ *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID; -+ result = true; -+ break; -+ case ENGINE_ID_DIGD: -+ *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID; -+ result = true; -+ break; -+ case ENGINE_ID_DIGE: -+ *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID; -+ result = true; -+ break; -+ case ENGINE_ID_DIGF: -+ *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID; -+ result = true; -+ break; -+ case ENGINE_ID_DIGG: -+ *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID; -+ result = true; -+ break; -+ case ENGINE_ID_DACA: -+ *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID; -+ result = true; -+ break; -+ default: -+ break; -+ } -+ -+ return result; -+} -+ -+static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action) -+{ -+ uint8_t atom_action = 0; -+ -+ switch (action) { -+ case ENCODER_CONTROL_ENABLE: -+ atom_action = ATOM_ENABLE; -+ break; -+ case ENCODER_CONTROL_DISABLE: -+ atom_action = ATOM_DISABLE; -+ break; -+ case ENCODER_CONTROL_SETUP: -+ atom_action = ATOM_ENCODER_CMD_STREAM_SETUP; -+ break; -+ case ENCODER_CONTROL_INIT: -+ atom_action = ATOM_ENCODER_INIT; -+ break; -+ default: -+ BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */ -+ break; -+ } -+ -+ return atom_action; -+} -+ -+static uint8_t disp_power_gating_action_to_atom( -+ enum bp_pipe_control_action action) -+{ -+ uint8_t atom_pipe_action = 0; -+ -+ switch (action) { -+ case ASIC_PIPE_DISABLE: -+ atom_pipe_action = ATOM_DISABLE; -+ break; -+ case ASIC_PIPE_ENABLE: -+ atom_pipe_action = ATOM_ENABLE; -+ break; -+ case ASIC_PIPE_INIT: -+ atom_pipe_action = ATOM_INIT; -+ break; -+ default: -+ ASSERT_CRITICAL(false); /* Unhandle action in driver! */ -+ break; -+ } -+ -+ return atom_pipe_action; -+} -+ -+static bool dc_clock_type_to_atom( -+ enum bp_dce_clock_type id, -+ uint32_t *atom_clock_type) -+{ -+ bool retCode = true; -+ -+ if (atom_clock_type != NULL) { -+ switch (id) { -+ case DCECLOCK_TYPE_DISPLAY_CLOCK: -+ *atom_clock_type = DCE_CLOCK_TYPE_DISPCLK; -+ break; -+ -+ case DCECLOCK_TYPE_DPREFCLK: -+ *atom_clock_type = DCE_CLOCK_TYPE_DPREFCLK; -+ break; -+ -+ default: -+ ASSERT_CRITICAL(false); /* Unhandle action in driver! */ -+ break; -+ } -+ } -+ -+ return retCode; -+} -+ -+static uint8_t transmitter_color_depth_to_atom(enum transmitter_color_depth id) -+{ -+ uint8_t atomColorDepth = 0; -+ -+ switch (id) { -+ case TRANSMITTER_COLOR_DEPTH_24: -+ atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_DIS; -+ break; -+ case TRANSMITTER_COLOR_DEPTH_30: -+ atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_5_4; -+ break; -+ case TRANSMITTER_COLOR_DEPTH_36: -+ atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_3_2; -+ break; -+ case TRANSMITTER_COLOR_DEPTH_48: -+ atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_2_1; -+ break; -+ default: -+ ASSERT_CRITICAL(false); /* Unhandle action in driver! */ -+ break; -+ } -+ -+ return atomColorDepth; -+} -+ -+/* function table */ -+static const struct command_table_helper command_table_helper_funcs = { -+ .controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom2, -+ .encoder_action_to_atom = encoder_action_to_atom, -+ .engine_bp_to_atom = engine_bp_to_atom, -+ .clock_source_id_to_atom = clock_source_id_to_atom, -+ .clock_source_id_to_atom_phy_clk_src_id = -+ clock_source_id_to_atom_phy_clk_src_id, -+ .signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode, -+ .hpd_sel_to_atom = hpd_sel_to_atom, -+ .dig_encoder_sel_to_atom = dig_encoder_sel_to_atom, -+ .phy_id_to_atom = phy_id_to_atom, -+ .disp_power_gating_action_to_atom = disp_power_gating_action_to_atom, -+ .clock_source_id_to_ref_clk_src = NULL, -+ .transmitter_bp_to_atom = NULL, -+ .encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom2, -+ .encoder_mode_bp_to_atom = -+ dal_cmd_table_helper_encoder_mode_bp_to_atom2, -+ .dc_clock_type_to_atom = dc_clock_type_to_atom, -+ .transmitter_color_depth_to_atom = transmitter_color_depth_to_atom, -+}; -+ -+/* -+ * dal_cmd_tbl_helper_dce110_get_table -+ * -+ * @brief -+ * Initialize command table helper functions -+ * -+ * @param -+ * const struct command_table_helper **h - [out] struct of functions -+ * -+ */ -+const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2() -+{ -+ return &command_table_helper_funcs; -+} -diff --git a/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h -new file mode 100644 -index 0000000..abf28a0 ---- /dev/null -+++ b/drivers/gpu/drm/amd/display/dc/bios/dce112/command_table_helper2_dce112.h -@@ -0,0 +1,34 @@ -+/* -+ * Copyright 2012-15 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: AMD -+ * -+ */ -+ -+#ifndef __DAL_COMMAND_TABLE_HELPER2_DCE112_H__ -+#define __DAL_COMMAND_TABLE_HELPER2_DCE112_H__ -+ -+struct command_table_helper; -+ -+/* Initialize command table helper functions */ -+const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table2(void); -+ -+#endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */ --- -2.7.4 - |