drm/amd/display: refactor ddc logic from dc_link_ddc to link_ddc
authorWenjing Liu <wenjing.liu@amd.com>
Mon, 12 Dec 2022 18:52:57 +0000 (13:52 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 13 Jan 2023 19:57:40 +0000 (14:57 -0500)
[why]
1. Move dd_link_ddc functions to link_ddc.
2. Move link ddc functions declaration exposed in dc to link.h
3. Move link ddc functions declaration exposed in dm to dc_link.h
4. Remove i2caux_interface.h file

Tested-by: Daniel Wheeler <Daniel.Wheeler@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
38 files changed:
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/dc/Makefile
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c [deleted file]
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc_ddc_types.h
drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c
drivers/gpu/drm/amd/display/dc/dcn301/dcn301_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn302/dcn302_resource.c
drivers/gpu/drm/amd/display/dc/dcn303/dcn303_resource.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h [deleted file]
drivers/gpu/drm/amd/display/dc/inc/hw/aux_engine.h
drivers/gpu/drm/amd/display/dc/inc/link.h
drivers/gpu/drm/amd/display/dc/link/Makefile
drivers/gpu/drm/amd/display/dc/link/link_ddc.c [new file with mode: 0644]
drivers/gpu/drm/amd/display/dc/link/link_ddc.h [new file with mode: 0644]
drivers/gpu/drm/amd/display/include/i2caux_interface.h [deleted file]

index 23ed2e1da16d4c46ed54a1bdee445579d54329fd..7bf21bb52a7dd958b282bf9f60be8a036fa02a80 100644 (file)
@@ -66,7 +66,6 @@
 
 #include "ivsrcid/ivsrcid_vislands30.h"
 
-#include "i2caux_interface.h"
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/types.h>
index 41f35d75d0a8784906c647538bdb206499def873..bbeeee7c5d7c5653d37ba664135a2c4ad273abe0 100644 (file)
 #include "dc.h"
 #include "dm_helpers.h"
 
-#include "dc_link_ddc.h"
 #include "dc_link_dp.h"
 #include "ddc_service_types.h"
 #include "dpcd_defs.h"
 
-#include "i2caux_interface.h"
 #include "dmub_cmd.h"
 #if defined(CONFIG_DEBUG_FS)
 #include "amdgpu_dm_debugfs.h"
index b9effadfc4bb7f6adcfa7bde0bf04b6f12ad10c7..4438f3c16636b1c753da31e8923768cdf02cb582 100644 (file)
@@ -64,8 +64,8 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI
 
 include $(AMD_DC)
 
-DISPLAY_CORE = dc.o  dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
-dc_surface.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o \
+DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
+dc_surface.o dc_link_dp.o dc_debug.o dc_stream.o \
 dc_link_enc_cfg.o dc_link_dpia.o dc_link_dpcd.o
 
 DISPLAY_CORE += dc_vm_helper.o
index a1a00f432168efdaaedd1920b613e7b6b241412e..27af9d3c2b73d66a96094cf35cb569181f5bac56 100644 (file)
@@ -33,7 +33,6 @@
 #include "include/gpio_service_interface.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_table.h"
index 074e70a5c458e3e304cc0f9ba35747d57b59ec2c..8ca50c0888586ea9225391f19f17fc934a751470 100644 (file)
@@ -32,7 +32,6 @@
 #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"
index 5f3108728beb76ee842968b7fa587d8a5987af0d..53e586fc150102bb0613e52d83ddebc03e0603fa 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "resource.h"
 
+#include "gpio_service_interface.h"
 #include "clk_mgr.h"
 #include "clock_source.h"
 #include "dc_bios_types.h"
@@ -53,7 +54,7 @@
 #include "link_enc_cfg.h"
 
 #include "dc_link.h"
-#include "dc_link_ddc.h"
+#include "link.h"
 #include "dm_helpers.h"
 #include "mem_input.h"
 
@@ -68,8 +69,6 @@
 
 #include "dmub/dmub_srv.h"
 
-#include "i2caux_interface.h"
-
 #include "dce/dmub_psr.h"
 
 #include "dce/dmub_hw_lock_mgr.h"
index 13e33f581e7332de400f06090a8c90fff2470d17..b5572f5202ca5ffcbff2d97f86fbc8545a099f53 100644 (file)
@@ -34,7 +34,7 @@
 #include "core_status.h"
 #include "dc_link_dp.h"
 #include "dc_link_dpia.h"
-#include "dc_link_ddc.h"
+#include "link/link_ddc.h"
 #include "link_hwss.h"
 #include "link.h"
 #include "opp.h"
@@ -80,7 +80,7 @@ static void dc_link_destruct(struct dc_link *link)
        }
 
        if (link->ddc)
-               dal_ddc_service_destroy(&link->ddc);
+               link_destroy_ddc_service(&link->ddc);
 
        if (link->panel_cntl)
                link->panel_cntl->funcs->destroy(&link->panel_cntl);
@@ -277,7 +277,7 @@ bool dc_link_is_dp_sink_present(struct dc_link *link)
                (connector_id == CONNECTOR_ID_EDP) ||
                (connector_id == CONNECTOR_ID_USBC));
 
-       ddc = dal_ddc_service_get_ddc_pin(link->ddc);
+       ddc = get_ddc_pin(link->ddc);
 
        if (!ddc) {
                BREAK_TO_DEBUGGER();
@@ -422,11 +422,179 @@ static enum signal_type decide_signal_from_strap_and_dongle_type(enum display_do
        return signal;
 }
 
+static bool i2c_read(
+       struct ddc_service *ddc,
+       uint32_t address,
+       uint8_t *buffer,
+       uint32_t len)
+{
+       uint8_t offs_data = 0;
+       struct i2c_payload payloads[2] = {
+               {
+               .write = true,
+               .address = address,
+               .length = 1,
+               .data = &offs_data },
+               {
+               .write = false,
+               .address = address,
+               .length = len,
+               .data = buffer } };
+
+       struct i2c_command command = {
+               .payloads = payloads,
+               .number_of_payloads = 2,
+               .engine = DDC_I2C_COMMAND_ENGINE,
+               .speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
+
+       return dm_helpers_submit_i2c(
+                       ddc->ctx,
+                       ddc->link,
+                       &command);
+}
+
+enum {
+       DP_SINK_CAP_SIZE =
+               DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV + 1
+};
+
+static void query_dp_dual_mode_adaptor(
+       struct ddc_service *ddc,
+       struct display_sink_capability *sink_cap)
+{
+       uint8_t i;
+       bool is_valid_hdmi_signature;
+       enum display_dongle_type *dongle = &sink_cap->dongle_type;
+       uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
+       bool is_type2_dongle = false;
+       int retry_count = 2;
+       struct dp_hdmi_dongle_signature_data *dongle_signature;
+
+       /* Assume we have no valid DP passive dongle connected */
+       *dongle = DISPLAY_DONGLE_NONE;
+       sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
+
+       /* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
+       if (!i2c_read(
+               ddc,
+               DP_HDMI_DONGLE_ADDRESS,
+               type2_dongle_buf,
+               sizeof(type2_dongle_buf))) {
+               /* Passive HDMI dongles can sometimes fail here without retrying*/
+               while (retry_count > 0) {
+                       if (i2c_read(ddc,
+                               DP_HDMI_DONGLE_ADDRESS,
+                               type2_dongle_buf,
+                               sizeof(type2_dongle_buf)))
+                               break;
+                       retry_count--;
+               }
+               if (retry_count == 0) {
+                       *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
+                       sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
+
+                       CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
+                                       "DP-DVI passive dongle %dMhz: ",
+                                       DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
+                       return;
+               }
+       }
+
+       /* Check if Type 2 dongle.*/
+       if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
+               is_type2_dongle = true;
+
+       dongle_signature =
+               (struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
+
+       is_valid_hdmi_signature = true;
+
+       /* Check EOT */
+       if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
+               is_valid_hdmi_signature = false;
+       }
+
+       /* Check signature */
+       for (i = 0; i < sizeof(dongle_signature->id); ++i) {
+               /* If its not the right signature,
+                * skip mismatch in subversion byte.*/
+               if (dongle_signature->id[i] !=
+                       dp_hdmi_dongle_signature_str[i] && i != 3) {
+
+                       if (is_type2_dongle) {
+                               is_valid_hdmi_signature = false;
+                               break;
+                       }
+
+               }
+       }
+
+       if (is_type2_dongle) {
+               uint32_t max_tmds_clk =
+                       type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
+
+               max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
+
+               if (0 == max_tmds_clk ||
+                               max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
+                               max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
+                       *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
+
+                       CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
+                                       sizeof(type2_dongle_buf),
+                                       "DP-DVI passive dongle %dMhz: ",
+                                       DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
+               } else {
+                       if (is_valid_hdmi_signature == true) {
+                               *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
+
+                               CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
+                                               sizeof(type2_dongle_buf),
+                                               "Type 2 DP-HDMI passive dongle %dMhz: ",
+                                               max_tmds_clk);
+                       } else {
+                               *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
+
+                               CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
+                                               sizeof(type2_dongle_buf),
+                                               "Type 2 DP-HDMI passive dongle (no signature) %dMhz: ",
+                                               max_tmds_clk);
+
+                       }
+
+                       /* Multiply by 1000 to convert to kHz. */
+                       sink_cap->max_hdmi_pixel_clock =
+                               max_tmds_clk * 1000;
+               }
+               sink_cap->is_dongle_type_one = false;
+
+       } else {
+               if (is_valid_hdmi_signature == true) {
+                       *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
+
+                       CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
+                                       sizeof(type2_dongle_buf),
+                                       "Type 1 DP-HDMI passive dongle %dMhz: ",
+                                       sink_cap->max_hdmi_pixel_clock / 1000);
+               } else {
+                       *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
+
+                       CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
+                                       sizeof(type2_dongle_buf),
+                                       "Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
+                                       sink_cap->max_hdmi_pixel_clock / 1000);
+               }
+               sink_cap->is_dongle_type_one = true;
+       }
+
+       return;
+}
+
 static enum signal_type dp_passive_dongle_detection(struct ddc_service *ddc,
                                                    struct display_sink_capability *sink_cap,
                                                    struct audio_support *audio_support)
 {
-       dal_ddc_service_i2c_query_dp_dual_mode_adaptor(ddc, sink_cap);
+       query_dp_dual_mode_adaptor(ddc, sink_cap);
 
        return decide_signal_from_strap_and_dongle_type(sink_cap->dongle_type,
                                                        audio_support);
@@ -1046,11 +1214,11 @@ static bool detect_link_and_local_sink(struct dc_link *link,
                else
                        link->dpcd_sink_count = 1;
 
-               dal_ddc_service_set_transaction_type(link->ddc,
+               set_ddc_transaction_type(link->ddc,
                                                     sink_caps.transaction_type);
 
                link->aux_mode =
-                       dal_ddc_service_is_in_aux_transaction_mode(link->ddc);
+                       link_is_in_aux_transaction_mode(link->ddc);
 
                sink_init_data.link = link;
                sink_init_data.sink_signal = sink_caps.signal;
@@ -1265,7 +1433,7 @@ static enum channel_id get_ddc_line(struct dc_link *link)
 
        channel = CHANNEL_ID_UNKNOWN;
 
-       ddc = dal_ddc_service_get_ddc_pin(link->ddc);
+       ddc = get_ddc_pin(link->ddc);
 
        if (ddc) {
                switch (dal_ddc_get_line(ddc)) {
@@ -1502,7 +1670,7 @@ static bool dc_link_construct_legacy(struct dc_link *link,
        ddc_service_init_data.ctx = link->ctx;
        ddc_service_init_data.id = link->link_id;
        ddc_service_init_data.link = link;
-       link->ddc = dal_ddc_service_create(&ddc_service_init_data);
+       link->ddc = link_create_ddc_service(&ddc_service_init_data);
 
        if (!link->ddc) {
                DC_ERROR("Failed to create ddc_service!\n");
@@ -1515,7 +1683,7 @@ static bool dc_link_construct_legacy(struct dc_link *link,
        }
 
        link->ddc_hw_inst =
-               dal_ddc_get_line(dal_ddc_service_get_ddc_pin(link->ddc));
+               dal_ddc_get_line(get_ddc_pin(link->ddc));
 
 
        if (link->dc->res_pool->funcs->panel_cntl_create &&
@@ -1652,7 +1820,7 @@ link_enc_create_fail:
        if (link->panel_cntl != NULL)
                link->panel_cntl->funcs->destroy(&link->panel_cntl);
 panel_cntl_create_fail:
-       dal_ddc_service_destroy(&link->ddc);
+       link_destroy_ddc_service(&link->ddc);
 ddc_create_fail:
 create_fail:
 
@@ -1710,7 +1878,7 @@ static bool dc_link_construct_dpia(struct dc_link *link,
        /* Set indicator for dpia link so that ddc won't be created */
        ddc_service_init_data.is_dpia_link = true;
 
-       link->ddc = dal_ddc_service_create(&ddc_service_init_data);
+       link->ddc = link_create_ddc_service(&ddc_service_init_data);
        if (!link->ddc) {
                DC_ERROR("Failed to create ddc_service!\n");
                goto ddc_create_fail;
@@ -2178,7 +2346,7 @@ static void write_i2c_retimer_setting(
                                        value = settings->reg_settings[i].i2c_reg_val;
                                else {
                                        i2c_success =
-                                               dal_ddc_service_query_ddc_data(
+                                               link_query_ddc_data(
                                                pipe_ctx->stream->link->ddc,
                                                slave_address, &offset, 1, &value, 1);
                                        if (!i2c_success)
@@ -2228,7 +2396,7 @@ static void write_i2c_retimer_setting(
                                                value = settings->reg_settings_6g[i].i2c_reg_val;
                                        else {
                                                i2c_success =
-                                                               dal_ddc_service_query_ddc_data(
+                                                               link_query_ddc_data(
                                                                pipe_ctx->stream->link->ddc,
                                                                slave_address, &offset, 1, &value, 1);
                                                if (!i2c_success)
@@ -2526,7 +2694,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
        }
 
        if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
-               dal_ddc_service_write_scdc_data(
+               write_scdc_data(
                        stream->link->ddc,
                        stream->phy_pix_clk,
                        stream->timing.flags.LTE_340MCSC_SCRAMBLE);
@@ -2547,7 +2715,7 @@ static void enable_link_hdmi(struct pipe_ctx *pipe_ctx)
                        stream->phy_pix_clk);
 
        if (dc_is_hdmi_signal(pipe_ctx->stream->signal))
-               dal_ddc_service_read_scdc_data(link->ddc);
+               read_scdc_data(link->ddc);
 }
 
 static void enable_link_lvds(struct pipe_ctx *pipe_ctx)
@@ -4312,7 +4480,7 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
                unsigned short masked_chip_caps = link->chip_caps &
                                EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK;
                //Need to inform that sink is going to use legacy HDMI mode.
-               dal_ddc_service_write_scdc_data(
+               write_scdc_data(
                        link->ddc,
                        165000,//vbios only handles 165Mhz.
                        false);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
deleted file mode 100644 (file)
index 6512313..0000000
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * 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 "dm_helpers.h"
-#include "gpio_service_interface.h"
-#include "include/ddc_service_types.h"
-#include "include/grph_object_id.h"
-#include "include/dpcd_defs.h"
-#include "include/logger_interface.h"
-#include "include/vector.h"
-#include "core_types.h"
-#include "dc_link_ddc.h"
-#include "dce/dce_aux.h"
-#include "dmub/inc/dmub_cmd.h"
-#include "link_dpcd.h"
-#include "include/dal_asic_id.h"
-
-#define DC_LOGGER_INIT(logger)
-
-static const uint8_t DP_VGA_DONGLE_BRANCH_DEV_NAME[] = "DpVga";
-/* DP to Dual link DVI converter */
-static const uint8_t DP_DVI_CONVERTER_ID_4[] = "m2DVIa";
-static const uint8_t DP_DVI_CONVERTER_ID_5[] = "3393N2";
-
-#define AUX_POWER_UP_WA_DELAY 500
-#define I2C_OVER_AUX_DEFER_WA_DELAY 70
-#define DPVGA_DONGLE_AUX_DEFER_WA_DELAY 40
-#define I2C_OVER_AUX_DEFER_WA_DELAY_1MS 1
-
-/* CV smart dongle slave address for retrieving supported HDTV modes*/
-#define CV_SMART_DONGLE_ADDRESS 0x20
-/* DVI-HDMI dongle slave address for retrieving dongle signature*/
-#define DVI_HDMI_DONGLE_ADDRESS 0x68
-struct dvi_hdmi_dongle_signature_data {
-       int8_t vendor[3];/* "AMD" */
-       uint8_t version[2];
-       uint8_t size;
-       int8_t id[11];/* "6140063500G"*/
-};
-/* DP-HDMI dongle slave address for retrieving dongle signature*/
-#define DP_HDMI_DONGLE_ADDRESS 0x40
-static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR";
-#define DP_HDMI_DONGLE_SIGNATURE_EOT 0x04
-
-struct dp_hdmi_dongle_signature_data {
-       int8_t id[15];/* "DP-HDMI ADAPTOR"*/
-       uint8_t eot;/* end of transmition '\x4' */
-};
-
-/* SCDC Address defines (HDMI 2.0)*/
-#define HDMI_SCDC_WRITE_UPDATE_0_ARRAY 3
-#define HDMI_SCDC_ADDRESS  0x54
-#define HDMI_SCDC_SINK_VERSION 0x01
-#define HDMI_SCDC_SOURCE_VERSION 0x02
-#define HDMI_SCDC_UPDATE_0 0x10
-#define HDMI_SCDC_TMDS_CONFIG 0x20
-#define HDMI_SCDC_SCRAMBLER_STATUS 0x21
-#define HDMI_SCDC_CONFIG_0 0x30
-#define HDMI_SCDC_STATUS_FLAGS 0x40
-#define HDMI_SCDC_ERR_DETECT 0x50
-#define HDMI_SCDC_TEST_CONFIG 0xC0
-
-union hdmi_scdc_update_read_data {
-       uint8_t byte[2];
-       struct {
-               uint8_t STATUS_UPDATE:1;
-               uint8_t CED_UPDATE:1;
-               uint8_t RR_TEST:1;
-               uint8_t RESERVED:5;
-               uint8_t RESERVED2:8;
-       } fields;
-};
-
-union hdmi_scdc_status_flags_data {
-       uint8_t byte;
-       struct {
-               uint8_t CLOCK_DETECTED:1;
-               uint8_t CH0_LOCKED:1;
-               uint8_t CH1_LOCKED:1;
-               uint8_t CH2_LOCKED:1;
-               uint8_t RESERVED:4;
-       } fields;
-};
-
-union hdmi_scdc_ced_data {
-       uint8_t byte[7];
-       struct {
-               uint8_t CH0_8LOW:8;
-               uint8_t CH0_7HIGH:7;
-               uint8_t CH0_VALID:1;
-               uint8_t CH1_8LOW:8;
-               uint8_t CH1_7HIGH:7;
-               uint8_t CH1_VALID:1;
-               uint8_t CH2_8LOW:8;
-               uint8_t CH2_7HIGH:7;
-               uint8_t CH2_VALID:1;
-               uint8_t CHECKSUM:8;
-               uint8_t RESERVED:8;
-               uint8_t RESERVED2:8;
-               uint8_t RESERVED3:8;
-               uint8_t RESERVED4:4;
-       } fields;
-};
-
-struct i2c_payloads {
-       struct vector payloads;
-};
-
-struct aux_payloads {
-       struct vector payloads;
-};
-
-static bool dal_ddc_i2c_payloads_create(
-               struct dc_context *ctx,
-               struct i2c_payloads *payloads,
-               uint32_t count)
-{
-       if (dal_vector_construct(
-               &payloads->payloads, ctx, count, sizeof(struct i2c_payload)))
-               return true;
-
-       return false;
-}
-
-static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p)
-{
-       return (struct i2c_payload *)p->payloads.container;
-}
-
-static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p)
-{
-       return p->payloads.count;
-}
-
-#define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b))
-
-void dal_ddc_i2c_payloads_add(
-       struct i2c_payloads *payloads,
-       uint32_t address,
-       uint32_t len,
-       uint8_t *data,
-       bool write)
-{
-       uint32_t payload_size = EDID_SEGMENT_SIZE;
-       uint32_t pos;
-
-       for (pos = 0; pos < len; pos += payload_size) {
-               struct i2c_payload payload = {
-                       .write = write,
-                       .address = address,
-                       .length = DDC_MIN(payload_size, len - pos),
-                       .data = data + pos };
-               dal_vector_append(&payloads->payloads, &payload);
-       }
-
-}
-
-static void ddc_service_construct(
-       struct ddc_service *ddc_service,
-       struct ddc_service_init_data *init_data)
-{
-       enum connector_id connector_id =
-               dal_graphics_object_id_get_connector_id(init_data->id);
-
-       struct gpio_service *gpio_service = init_data->ctx->gpio_service;
-       struct graphics_object_i2c_info i2c_info;
-       struct gpio_ddc_hw_info hw_info;
-       struct dc_bios *dcb = init_data->ctx->dc_bios;
-
-       ddc_service->link = init_data->link;
-       ddc_service->ctx = init_data->ctx;
-
-       if (init_data->is_dpia_link ||
-           dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) {
-               ddc_service->ddc_pin = NULL;
-       } else {
-               DC_LOGGER_INIT(ddc_service->ctx->logger);
-               DC_LOG_DC("BIOS object table - i2c_line: %d", i2c_info.i2c_line);
-               DC_LOG_DC("BIOS object table - i2c_engine_id: %d", i2c_info.i2c_engine_id);
-
-               hw_info.ddc_channel = i2c_info.i2c_line;
-               if (ddc_service->link != NULL)
-                       hw_info.hw_supported = i2c_info.i2c_hw_assist;
-               else
-                       hw_info.hw_supported = false;
-
-               ddc_service->ddc_pin = dal_gpio_create_ddc(
-                       gpio_service,
-                       i2c_info.gpio_info.clk_a_register_index,
-                       1 << i2c_info.gpio_info.clk_a_shift,
-                       &hw_info);
-       }
-
-       ddc_service->flags.EDID_QUERY_DONE_ONCE = false;
-       ddc_service->flags.FORCE_READ_REPEATED_START = false;
-       ddc_service->flags.EDID_STRESS_READ = false;
-
-       ddc_service->flags.IS_INTERNAL_DISPLAY =
-               connector_id == CONNECTOR_ID_EDP ||
-               connector_id == CONNECTOR_ID_LVDS;
-
-       ddc_service->wa.raw = 0;
-}
-
-struct ddc_service *dal_ddc_service_create(
-       struct ddc_service_init_data *init_data)
-{
-       struct ddc_service *ddc_service;
-
-       ddc_service = kzalloc(sizeof(struct ddc_service), GFP_KERNEL);
-
-       if (!ddc_service)
-               return NULL;
-
-       ddc_service_construct(ddc_service, init_data);
-       return ddc_service;
-}
-
-static void ddc_service_destruct(struct ddc_service *ddc)
-{
-       if (ddc->ddc_pin)
-               dal_gpio_destroy_ddc(&ddc->ddc_pin);
-}
-
-void dal_ddc_service_destroy(struct ddc_service **ddc)
-{
-       if (!ddc || !*ddc) {
-               BREAK_TO_DEBUGGER();
-               return;
-       }
-       ddc_service_destruct(*ddc);
-       kfree(*ddc);
-       *ddc = NULL;
-}
-
-enum ddc_service_type dal_ddc_service_get_type(struct ddc_service *ddc)
-{
-       return DDC_SERVICE_TYPE_CONNECTOR;
-}
-
-void dal_ddc_service_set_transaction_type(
-       struct ddc_service *ddc,
-       enum ddc_transaction_type type)
-{
-       ddc->transaction_type = type;
-}
-
-bool dal_ddc_service_is_in_aux_transaction_mode(struct ddc_service *ddc)
-{
-       switch (ddc->transaction_type) {
-       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX:
-       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER:
-       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_RETRY_DEFER:
-               return true;
-       default:
-               break;
-       }
-       return false;
-}
-
-void ddc_service_set_dongle_type(struct ddc_service *ddc,
-               enum display_dongle_type dongle_type)
-{
-       ddc->dongle_type = dongle_type;
-}
-
-static uint32_t defer_delay_converter_wa(
-       struct ddc_service *ddc,
-       uint32_t defer_delay)
-{
-       struct dc_link *link = ddc->link;
-
-       if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER &&
-               link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 &&
-               (link->dpcd_caps.branch_fw_revision[0] < 0x01 ||
-                               (link->dpcd_caps.branch_fw_revision[0] == 0x01 &&
-                               link->dpcd_caps.branch_fw_revision[1] < 0x40)) &&
-               !memcmp(link->dpcd_caps.branch_dev_name,
-                   DP_VGA_DONGLE_BRANCH_DEV_NAME,
-                       sizeof(link->dpcd_caps.branch_dev_name)))
-
-               return defer_delay > DPVGA_DONGLE_AUX_DEFER_WA_DELAY ?
-                       defer_delay : DPVGA_DONGLE_AUX_DEFER_WA_DELAY;
-
-       if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 &&
-           !memcmp(link->dpcd_caps.branch_dev_name,
-                   DP_DVI_CONVERTER_ID_4,
-                   sizeof(link->dpcd_caps.branch_dev_name)))
-               return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY ?
-                       defer_delay : I2C_OVER_AUX_DEFER_WA_DELAY;
-       if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_006037 &&
-           !memcmp(link->dpcd_caps.branch_dev_name,
-                   DP_DVI_CONVERTER_ID_5,
-                   sizeof(link->dpcd_caps.branch_dev_name)))
-               return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY_1MS ?
-                       I2C_OVER_AUX_DEFER_WA_DELAY_1MS : defer_delay;
-
-       return defer_delay;
-}
-
-#define DP_TRANSLATOR_DELAY 5
-
-uint32_t get_defer_delay(struct ddc_service *ddc)
-{
-       uint32_t defer_delay = 0;
-
-       switch (ddc->transaction_type) {
-       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX:
-               if ((DISPLAY_DONGLE_DP_VGA_CONVERTER == ddc->dongle_type) ||
-                       (DISPLAY_DONGLE_DP_DVI_CONVERTER == ddc->dongle_type) ||
-                       (DISPLAY_DONGLE_DP_HDMI_CONVERTER ==
-                               ddc->dongle_type)) {
-
-                       defer_delay = DP_TRANSLATOR_DELAY;
-
-                       defer_delay =
-                               defer_delay_converter_wa(ddc, defer_delay);
-
-               } else /*sink has a delay different from an Active Converter*/
-                       defer_delay = 0;
-               break;
-       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER:
-               defer_delay = DP_TRANSLATOR_DELAY;
-               break;
-       default:
-               break;
-       }
-       return defer_delay;
-}
-
-static bool i2c_read(
-       struct ddc_service *ddc,
-       uint32_t address,
-       uint8_t *buffer,
-       uint32_t len)
-{
-       uint8_t offs_data = 0;
-       struct i2c_payload payloads[2] = {
-               {
-               .write = true,
-               .address = address,
-               .length = 1,
-               .data = &offs_data },
-               {
-               .write = false,
-               .address = address,
-               .length = len,
-               .data = buffer } };
-
-       struct i2c_command command = {
-               .payloads = payloads,
-               .number_of_payloads = 2,
-               .engine = DDC_I2C_COMMAND_ENGINE,
-               .speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
-
-       return dm_helpers_submit_i2c(
-                       ddc->ctx,
-                       ddc->link,
-                       &command);
-}
-
-void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
-       struct ddc_service *ddc,
-       struct display_sink_capability *sink_cap)
-{
-       uint8_t i;
-       bool is_valid_hdmi_signature;
-       enum display_dongle_type *dongle = &sink_cap->dongle_type;
-       uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
-       bool is_type2_dongle = false;
-       int retry_count = 2;
-       struct dp_hdmi_dongle_signature_data *dongle_signature;
-
-       /* Assume we have no valid DP passive dongle connected */
-       *dongle = DISPLAY_DONGLE_NONE;
-       sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
-
-       /* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
-       if (!i2c_read(
-               ddc,
-               DP_HDMI_DONGLE_ADDRESS,
-               type2_dongle_buf,
-               sizeof(type2_dongle_buf))) {
-               /* Passive HDMI dongles can sometimes fail here without retrying*/
-               while (retry_count > 0) {
-                       if (i2c_read(ddc,
-                               DP_HDMI_DONGLE_ADDRESS,
-                               type2_dongle_buf,
-                               sizeof(type2_dongle_buf)))
-                               break;
-                       retry_count--;
-               }
-               if (retry_count == 0) {
-                       *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
-                       sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
-
-                       CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf),
-                                       "DP-DVI passive dongle %dMhz: ",
-                                       DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
-                       return;
-               }
-       }
-
-       /* Check if Type 2 dongle.*/
-       if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
-               is_type2_dongle = true;
-
-       dongle_signature =
-               (struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
-
-       is_valid_hdmi_signature = true;
-
-       /* Check EOT */
-       if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
-               is_valid_hdmi_signature = false;
-       }
-
-       /* Check signature */
-       for (i = 0; i < sizeof(dongle_signature->id); ++i) {
-               /* If its not the right signature,
-                * skip mismatch in subversion byte.*/
-               if (dongle_signature->id[i] !=
-                       dp_hdmi_dongle_signature_str[i] && i != 3) {
-
-                       if (is_type2_dongle) {
-                               is_valid_hdmi_signature = false;
-                               break;
-                       }
-
-               }
-       }
-
-       if (is_type2_dongle) {
-               uint32_t max_tmds_clk =
-                       type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
-
-               max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
-
-               if (0 == max_tmds_clk ||
-                               max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
-                               max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
-                       *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
-
-                       CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
-                                       sizeof(type2_dongle_buf),
-                                       "DP-DVI passive dongle %dMhz: ",
-                                       DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000);
-               } else {
-                       if (is_valid_hdmi_signature == true) {
-                               *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
-
-                               CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
-                                               sizeof(type2_dongle_buf),
-                                               "Type 2 DP-HDMI passive dongle %dMhz: ",
-                                               max_tmds_clk);
-                       } else {
-                               *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
-
-                               CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
-                                               sizeof(type2_dongle_buf),
-                                               "Type 2 DP-HDMI passive dongle (no signature) %dMhz: ",
-                                               max_tmds_clk);
-
-                       }
-
-                       /* Multiply by 1000 to convert to kHz. */
-                       sink_cap->max_hdmi_pixel_clock =
-                               max_tmds_clk * 1000;
-               }
-               sink_cap->is_dongle_type_one = false;
-
-       } else {
-               if (is_valid_hdmi_signature == true) {
-                       *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
-
-                       CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
-                                       sizeof(type2_dongle_buf),
-                                       "Type 1 DP-HDMI passive dongle %dMhz: ",
-                                       sink_cap->max_hdmi_pixel_clock / 1000);
-               } else {
-                       *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
-
-                       CONN_DATA_DETECT(ddc->link, type2_dongle_buf,
-                                       sizeof(type2_dongle_buf),
-                                       "Type 1 DP-HDMI passive dongle (no signature) %dMhz: ",
-                                       sink_cap->max_hdmi_pixel_clock / 1000);
-               }
-               sink_cap->is_dongle_type_one = true;
-       }
-
-       return;
-}
-
-enum {
-       DP_SINK_CAP_SIZE =
-               DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV + 1
-};
-
-bool dal_ddc_service_query_ddc_data(
-       struct ddc_service *ddc,
-       uint32_t address,
-       uint8_t *write_buf,
-       uint32_t write_size,
-       uint8_t *read_buf,
-       uint32_t read_size)
-{
-       bool success = true;
-       uint32_t payload_size =
-               dal_ddc_service_is_in_aux_transaction_mode(ddc) ?
-                       DEFAULT_AUX_MAX_DATA_SIZE : EDID_SEGMENT_SIZE;
-
-       uint32_t write_payloads =
-               (write_size + payload_size - 1) / payload_size;
-
-       uint32_t read_payloads =
-               (read_size + payload_size - 1) / payload_size;
-
-       uint32_t payloads_num = write_payloads + read_payloads;
-
-       if (!payloads_num)
-               return false;
-
-       if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
-               struct aux_payload payload;
-
-               payload.i2c_over_aux = true;
-               payload.address = address;
-               payload.reply = NULL;
-               payload.defer_delay = get_defer_delay(ddc);
-               payload.write_status_update = false;
-
-               if (write_size != 0) {
-                       payload.write = true;
-                       /* should not set mot (middle of transaction) to 0
-                        * if there are pending read payloads
-                        */
-                       payload.mot = !(read_size == 0);
-                       payload.length = write_size;
-                       payload.data = write_buf;
-
-                       success = dal_ddc_submit_aux_command(ddc, &payload);
-               }
-
-               if (read_size != 0 && success) {
-                       payload.write = false;
-                       /* should set mot (middle of transaction) to 0
-                        * since it is the last payload to send
-                        */
-                       payload.mot = false;
-                       payload.length = read_size;
-                       payload.data = read_buf;
-
-                       success = dal_ddc_submit_aux_command(ddc, &payload);
-               }
-       } else {
-               struct i2c_command command = {0};
-               struct i2c_payloads payloads;
-
-               if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num))
-                       return false;
-
-               command.payloads = dal_ddc_i2c_payloads_get(&payloads);
-               command.number_of_payloads = 0;
-               command.engine = DDC_I2C_COMMAND_ENGINE;
-               command.speed = ddc->ctx->dc->caps.i2c_speed_in_khz;
-
-               dal_ddc_i2c_payloads_add(
-                       &payloads, address, write_size, write_buf, true);
-
-               dal_ddc_i2c_payloads_add(
-                       &payloads, address, read_size, read_buf, false);
-
-               command.number_of_payloads =
-                       dal_ddc_i2c_payloads_get_count(&payloads);
-
-               success = dm_helpers_submit_i2c(
-                               ddc->ctx,
-                               ddc->link,
-                               &command);
-
-               dal_vector_destruct(&payloads.payloads);
-       }
-
-       return success;
-}
-
-bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
-               struct aux_payload *payload)
-{
-       uint32_t retrieved = 0;
-       bool ret = false;
-
-       if (!ddc)
-               return false;
-
-       if (!payload)
-               return false;
-
-       do {
-               struct aux_payload current_payload;
-               bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) >=
-                               payload->length;
-               uint32_t payload_length = is_end_of_payload ?
-                               payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE;
-
-               current_payload.address = payload->address;
-               current_payload.data = &payload->data[retrieved];
-               current_payload.defer_delay = payload->defer_delay;
-               current_payload.i2c_over_aux = payload->i2c_over_aux;
-               current_payload.length = payload_length;
-               /* set mot (middle of transaction) to false if it is the last payload */
-               current_payload.mot = is_end_of_payload ? payload->mot:true;
-               current_payload.write_status_update = false;
-               current_payload.reply = payload->reply;
-               current_payload.write = payload->write;
-
-               ret = dc_link_aux_transfer_with_retries(ddc, &current_payload);
-
-               retrieved += payload_length;
-       } while (retrieved < payload->length && ret == true);
-
-       return ret;
-}
-
-/* dc_link_aux_transfer_raw() - Attempt to transfer
- * the given aux payload.  This function does not perform
- * retries or handle error states.  The reply is returned
- * in the payload->reply and the result through
- * *operation_result.  Returns the number of bytes transferred,
- * or -1 on a failure.
- */
-int dc_link_aux_transfer_raw(struct ddc_service *ddc,
-               struct aux_payload *payload,
-               enum aux_return_code_type *operation_result)
-{
-       if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc ||
-           !ddc->ddc_pin) {
-               return dce_aux_transfer_dmub_raw(ddc, payload, operation_result);
-       } else {
-               return dce_aux_transfer_raw(ddc, payload, operation_result);
-       }
-}
-
-/* dc_link_aux_transfer_with_retries() - Attempt to submit an
- * aux payload, retrying on timeouts, defers, and busy states
- * as outlined in the DP spec.  Returns true if the request
- * was successful.
- *
- * Unless you want to implement your own retry semantics, this
- * is probably the one you want.
- */
-bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
-               struct aux_payload *payload)
-{
-       return dce_aux_transfer_with_retries(ddc, payload);
-}
-
-
-bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc,
-               uint32_t timeout)
-{
-       bool result = false;
-       struct ddc *ddc_pin = ddc->ddc_pin;
-
-       if ((ddc->link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
-                       !ddc->link->dc->debug.disable_fixed_vs_aux_timeout_wa &&
-                       ASICREV_IS_YELLOW_CARP(ddc->ctx->asic_id.hw_internal_rev)) {
-               /* Fixed VS workaround for AUX timeout */
-               const uint32_t fixed_vs_address = 0xF004F;
-               const uint8_t fixed_vs_data[4] = {0x1, 0x22, 0x63, 0xc};
-
-               core_link_write_dpcd(ddc->link,
-                               fixed_vs_address,
-                               fixed_vs_data,
-                               sizeof(fixed_vs_data));
-
-               timeout = 3072;
-       }
-
-       /* Do not try to access nonexistent DDC pin. */
-       if (ddc->link->ep_type != DISPLAY_ENDPOINT_PHY)
-               return true;
-
-       if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) {
-               ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout);
-               result = true;
-       }
-
-       return result;
-}
-
-/*test only function*/
-void dal_ddc_service_set_ddc_pin(
-       struct ddc_service *ddc_service,
-       struct ddc *ddc)
-{
-       ddc_service->ddc_pin = ddc;
-}
-
-struct ddc *dal_ddc_service_get_ddc_pin(struct ddc_service *ddc_service)
-{
-       return ddc_service->ddc_pin;
-}
-
-void dal_ddc_service_write_scdc_data(struct ddc_service *ddc_service,
-               uint32_t pix_clk,
-               bool lte_340_scramble)
-{
-       bool over_340_mhz = pix_clk > 340000 ? 1 : 0;
-       uint8_t slave_address = HDMI_SCDC_ADDRESS;
-       uint8_t offset = HDMI_SCDC_SINK_VERSION;
-       uint8_t sink_version = 0;
-       uint8_t write_buffer[2] = {0};
-       /*Lower than 340 Scramble bit from SCDC caps*/
-
-       if (ddc_service->link->local_sink &&
-               ddc_service->link->local_sink->edid_caps.panel_patch.skip_scdc_overwrite)
-               return;
-
-       dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
-                       sizeof(offset), &sink_version, sizeof(sink_version));
-       if (sink_version == 1) {
-               /*Source Version = 1*/
-               write_buffer[0] = HDMI_SCDC_SOURCE_VERSION;
-               write_buffer[1] = 1;
-               dal_ddc_service_query_ddc_data(ddc_service, slave_address,
-                               write_buffer, sizeof(write_buffer), NULL, 0);
-               /*Read Request from SCDC caps*/
-       }
-       write_buffer[0] = HDMI_SCDC_TMDS_CONFIG;
-
-       if (over_340_mhz) {
-               write_buffer[1] = 3;
-       } else if (lte_340_scramble) {
-               write_buffer[1] = 1;
-       } else {
-               write_buffer[1] = 0;
-       }
-       dal_ddc_service_query_ddc_data(ddc_service, slave_address, write_buffer,
-                       sizeof(write_buffer), NULL, 0);
-}
-
-void dal_ddc_service_read_scdc_data(struct ddc_service *ddc_service)
-{
-       uint8_t slave_address = HDMI_SCDC_ADDRESS;
-       uint8_t offset = HDMI_SCDC_TMDS_CONFIG;
-       uint8_t tmds_config = 0;
-
-       if (ddc_service->link->local_sink &&
-               ddc_service->link->local_sink->edid_caps.panel_patch.skip_scdc_overwrite)
-               return;
-
-       dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
-                       sizeof(offset), &tmds_config, sizeof(tmds_config));
-       if (tmds_config & 0x1) {
-               union hdmi_scdc_status_flags_data status_data = {0};
-               uint8_t scramble_status = 0;
-
-               offset = HDMI_SCDC_SCRAMBLER_STATUS;
-               dal_ddc_service_query_ddc_data(ddc_service, slave_address,
-                               &offset, sizeof(offset), &scramble_status,
-                               sizeof(scramble_status));
-               offset = HDMI_SCDC_STATUS_FLAGS;
-               dal_ddc_service_query_ddc_data(ddc_service, slave_address,
-                               &offset, sizeof(offset), &status_data.byte,
-                               sizeof(status_data.byte));
-       }
-}
-
index 51945593f74b613b3b0b432c806dc0de2213ed7a..815652da41265c516637433401b59167a641b2cc 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "inc/core_types.h"
 #include "link_hwss.h"
-#include "dc_link_ddc.h"
+#include "link/link_ddc.h"
 #include "core_status.h"
 #include "dpcd_defs.h"
 #include "dc_dmub_srv.h"
@@ -4866,7 +4866,7 @@ static void get_active_converter_info(
        /* decode converter info*/
        if (!ds_port.fields.PORT_PRESENT) {
                link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
-               ddc_service_set_dongle_type(link->ddc,
+               set_dongle_type(link->ddc,
                                link->dpcd_caps.dongle_type);
                link->dpcd_caps.is_branch_dev = false;
                return;
@@ -4974,7 +4974,7 @@ static void get_active_converter_info(
                }
        }
 
-       ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
+       set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
 
        {
                struct dp_sink_hw_fw_revision dp_hw_fw_revision;
@@ -5352,7 +5352,7 @@ static bool retrieve_link_cap(struct dc_link *link)
         * default to LTTPR timeout (3.2ms) first as a W/A for DP link layer
         * CTS 4.2.1.1 regression introduced by CTS specs requirement update.
         */
-       dc_link_aux_try_to_configure_timeout(link->ddc,
+       try_to_configure_aux_timeout(link->ddc,
                        LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD);
 
        status = dp_retrieve_lttpr_cap(link);
@@ -5393,7 +5393,7 @@ static bool retrieve_link_cap(struct dc_link *link)
        }
 
        if (!dp_is_lttpr_present(link))
-               dc_link_aux_try_to_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
+               try_to_configure_aux_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
 
        {
                union training_aux_rd_interval aux_rd_interval;
index 7769bd099a5a03dc0ad4990b7c53452ae3c03db9..7b036a772b0cae9620b2a0d1a38784eb5271ac28 100644 (file)
@@ -77,6 +77,32 @@ struct aux_reply_transaction_data {
        uint8_t *data;
 };
 
+struct aux_payload {
+       /* set following flag to read/write I2C data,
+        * reset it to read/write DPCD data */
+       bool i2c_over_aux;
+       /* set following flag to write data,
+        * reset it to read data */
+       bool write;
+       bool mot;
+       bool write_status_update;
+
+       uint32_t address;
+       uint32_t length;
+       uint8_t *data;
+       /*
+        * used to return the reply type of the transaction
+        * ignored if NULL
+        */
+       uint8_t *reply;
+       /* expressed in milliseconds
+        * zero means "use default value"
+        */
+       uint32_t defer_delay;
+
+};
+#define DEFAULT_AUX_MAX_DATA_SIZE 16
+
 struct i2c_payload {
        bool write;
        uint8_t address;
@@ -90,6 +116,8 @@ enum i2c_command_engine {
        I2C_COMMAND_ENGINE_HW
 };
 
+#define DDC_I2C_COMMAND_ENGINE I2C_COMMAND_ENGINE_SW
+
 struct i2c_command {
        struct i2c_payload *payloads;
        uint8_t number_of_payloads;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h b/drivers/gpu/drm/amd/display/dc/dc_hdmi_types.h
new file mode 100644 (file)
index 0000000..faf0d17
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2022 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 DC_HDMI_TYPES_H
+#define DC_HDMI_TYPES_H
+
+#include "os_types.h"
+
+/* Address range from 0x00 to 0x1F.*/
+#define DP_ADAPTOR_TYPE2_SIZE 0x20
+#define DP_ADAPTOR_TYPE2_REG_ID 0x10
+#define DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK 0x1D
+/* Identifies adaptor as Dual-mode adaptor */
+#define DP_ADAPTOR_TYPE2_ID 0xA0
+/* MHz*/
+#define DP_ADAPTOR_TYPE2_MAX_TMDS_CLK 600
+/* MHz*/
+#define DP_ADAPTOR_TYPE2_MIN_TMDS_CLK 25
+/* kHZ*/
+#define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000
+/* kHZ*/
+#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000
+
+struct dp_hdmi_dongle_signature_data {
+       int8_t id[15];/* "DP-HDMI ADAPTOR"*/
+       uint8_t eot;/* end of transmition '\x4' */
+};
+
+/* DP-HDMI dongle slave address for retrieving dongle signature*/
+#define DP_HDMI_DONGLE_ADDRESS 0x40
+static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR";
+#define DP_HDMI_DONGLE_SIGNATURE_EOT 0x04
+
+
+/* SCDC Address defines (HDMI 2.0)*/
+#define HDMI_SCDC_WRITE_UPDATE_0_ARRAY 3
+#define HDMI_SCDC_ADDRESS  0x54
+#define HDMI_SCDC_SINK_VERSION 0x01
+#define HDMI_SCDC_SOURCE_VERSION 0x02
+#define HDMI_SCDC_UPDATE_0 0x10
+#define HDMI_SCDC_TMDS_CONFIG 0x20
+#define HDMI_SCDC_SCRAMBLER_STATUS 0x21
+#define HDMI_SCDC_CONFIG_0 0x30
+#define HDMI_SCDC_CONFIG_1 0x31
+#define HDMI_SCDC_SOURCE_TEST_REQ 0x35
+#define HDMI_SCDC_STATUS_FLAGS 0x40
+#define HDMI_SCDC_ERR_DETECT 0x50
+#define HDMI_SCDC_TEST_CONFIG 0xC0
+
+union hdmi_scdc_update_read_data {
+       uint8_t byte[2];
+       struct {
+               uint8_t STATUS_UPDATE:1;
+               uint8_t CED_UPDATE:1;
+               uint8_t RR_TEST:1;
+               uint8_t RESERVED:5;
+               uint8_t RESERVED2:8;
+       } fields;
+};
+
+union hdmi_scdc_status_flags_data {
+       uint8_t byte;
+       struct {
+               uint8_t CLOCK_DETECTED:1;
+               uint8_t CH0_LOCKED:1;
+               uint8_t CH1_LOCKED:1;
+               uint8_t CH2_LOCKED:1;
+               uint8_t RESERVED:4;
+       } fields;
+};
+
+union hdmi_scdc_ced_data {
+       uint8_t byte[11];
+       struct {
+               uint8_t CH0_8LOW:8;
+               uint8_t CH0_7HIGH:7;
+               uint8_t CH0_VALID:1;
+               uint8_t CH1_8LOW:8;
+               uint8_t CH1_7HIGH:7;
+               uint8_t CH1_VALID:1;
+               uint8_t CH2_8LOW:8;
+               uint8_t CH2_7HIGH:7;
+               uint8_t CH2_VALID:1;
+               uint8_t CHECKSUM:8;
+               uint8_t RESERVED:8;
+               uint8_t RESERVED2:8;
+               uint8_t RESERVED3:8;
+               uint8_t RESERVED4:4;
+       } fields;
+};
+
+#endif /* DC_HDMI_TYPES_H */
index fbd6f11a63db5f787aee415c8bb4ebb6de32728c..d0d2d964d6012952a75830a605c110ac60d841e1 100644 (file)
@@ -31,6 +31,7 @@
 #include "grph_object_defs.h"
 
 struct link_resource;
+enum aux_return_code_type;
 
 enum dc_link_fec_state {
        dc_link_fec_not_ready,
@@ -591,4 +592,13 @@ unsigned int dc_dp_trace_get_link_loss_count(struct dc_link *link);
 
 /* Destruct the mst topology of the link and reset the allocated payload table */
 bool reset_cur_dp_mst_topology(struct dc_link *link);
+
+/* Attempt to transfer the given aux payload. This function does not perform
+ * retries or handle error states. The reply is returned in the payload->reply
+ * and the result through operation_result. Returns the number of bytes
+ * transferred,or -1 on a failure.
+ */
+int dc_link_aux_transfer_raw(struct ddc_service *ddc,
+               struct aux_payload *payload,
+               enum aux_return_code_type *operation_result);
 #endif /* DC_LINK_H_ */
index dc78e2404b4877b7cd6e804bedc57bc3cff806d5..c73a655bd68777f04994f204ac5c45b22f10817c 100644 (file)
@@ -33,6 +33,7 @@
 #include "fixed31_32.h"
 #include "irq_types.h"
 #include "dc_dp_types.h"
+#include "dc_hdmi_types.h"
 #include "dc_hw_types.h"
 #include "dal_types.h"
 #include "grph_object_defs.h"
index e69f1899fbf054f6b853fe2a9f9ebb1f2a5c30c9..c850ed49281f3919e7dc9c7633db3796069dd400 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef __DAL_AUX_ENGINE_DCE110_H__
 #define __DAL_AUX_ENGINE_DCE110_H__
 
-#include "i2caux_interface.h"
+#include "gpio_service_interface.h"
 #include "inc/hw/aux_engine.h"
 
 enum aux_return_code_type;
index 09260c23c3bdedafef592119f9a9abb86842dd43..fa314493ffc50050fe5d775bb47bdcf4837eaa74 100644 (file)
@@ -29,7 +29,6 @@
 #include "link_encoder.h"
 #include "dce_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 
 #include "gpio_service_interface.h"
index fbccb7263ad2578be59cf973d950b063f5257aa2..c4287147b8537ff5f05ad4304cd30f018bc67a98 100644 (file)
@@ -29,7 +29,6 @@
 #include "link_encoder.h"
 #include "dcn10_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 
 #include "gpio_service_interface.h"
index 2f9bfaeaba8d612382fd990591aebe0e23ad6435..51a57dae181145c76a1da75e13d469a33948208d 100644 (file)
@@ -29,7 +29,6 @@
 #include "link_encoder.h"
 #include "dcn20_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 
 #include "gpio_service_interface.h"
index 71c7237413efed2c61d9190e4fd4e4d56e2ca0f1..531f405d255443af1819fada7c6d9e89055af4f7 100644 (file)
@@ -62,7 +62,6 @@
 #include "dml/display_mode_vba.h"
 #include "dcn20_dccg.h"
 #include "dcn20_vmid.h"
-#include "dc_link_ddc.h"
 #include "dce/dce_panel_cntl.h"
 
 #include "navi10_ip_offset.h"
@@ -90,6 +89,7 @@
 
 #include "amdgpu_socbb.h"
 
+#include "link.h"
 #define DC_LOGGER_INIT(logger)
 
 #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL
@@ -1214,7 +1214,7 @@ static void dcn20_resource_destruct(struct dcn20_resource_pool *pool)
                dcn20_pp_smu_destroy(&pool->base.pp_smu);
 
        if (pool->base.oem_device != NULL)
-               dal_ddc_service_destroy(&pool->base.oem_device);
+               link_destroy_ddc_service(&pool->base.oem_device);
 }
 
 struct hubp *dcn20_hubp_create(
@@ -2769,7 +2769,7 @@ static bool dcn20_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
+               pool->base.oem_device = link_create_ddc_service(&ddc_init_data);
        } else {
                pool->base.oem_device = NULL;
        }
index 7f9ec59ef443ec30e24b6eee1d365377df9b4b92..8d31fa131cd60d4eda5e6febcec315ad023d84ad 100644 (file)
@@ -29,7 +29,6 @@
 #include "link_encoder.h"
 #include "dcn201_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 
 #include "gpio_service_interface.h"
index 0a1ba6e7081c2c78d189fa9f3b18552cfc9f7f74..eb9abb9f96986831b4a067c0d082a8d947288300 100644 (file)
@@ -31,7 +31,6 @@
 #include "dcn21_link_encoder.h"
 #include "stream_encoder.h"
 
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 
 #include "gpio_service_interface.h"
index 6f3c2fb60790ed473d787dba965a10327313f961..1fb8fd7afc95e6bf6f5b8daf432a00105a597710 100644 (file)
@@ -29,7 +29,6 @@
 #include "link_encoder.h"
 #include "dcn30_dio_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 /* #include "dcn3ag/dcn3ag_phy_fw.h" */
 
index c18c52a60100e5af2edae2879a1d0a2b1519e32e..feb4bb491525c600ceae6e1f34a0ae8d4e915890 100644 (file)
@@ -60,7 +60,7 @@
 #include "dml/display_mode_vba.h"
 #include "dcn30/dcn30_dccg.h"
 #include "dcn10/dcn10_resource.h"
-#include "dc_link_ddc.h"
+#include "link.h"
 #include "dce/dce_panel_cntl.h"
 
 #include "dcn30/dcn30_dwb.h"
@@ -1208,7 +1208,7 @@ static void dcn30_resource_destruct(struct dcn30_resource_pool *pool)
                dcn_dccg_destroy(&pool->base.dccg);
 
        if (pool->base.oem_device != NULL)
-               dal_ddc_service_destroy(&pool->base.oem_device);
+               link_destroy_ddc_service(&pool->base.oem_device);
 }
 
 static struct hubp *dcn30_hubp_create(
@@ -2590,7 +2590,7 @@ static bool dcn30_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
+               pool->base.oem_device = link_create_ddc_service(&ddc_init_data);
        } else {
                pool->base.oem_device = NULL;
        }
index c9fbaed239654b268163a211354d765ef09d0646..1b39a6e8a1ac5a74d56abd94629fae953593c785 100644 (file)
@@ -29,7 +29,6 @@
 #include "link_encoder.h"
 #include "dcn301_dio_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 #include "gpio_service_interface.h"
 
index 47cffd0e6830f70df8b0de62bf4ad9c7e5a6e48a..03ddf4f5f065c378deaa7dac3b8bc783f2a103ac 100644 (file)
@@ -47,6 +47,7 @@
 
 #include "dcn10/dcn10_resource.h"
 
+#include "link.h"
 #include "dce/dce_abm.h"
 #include "dce/dce_audio.h"
 #include "dce/dce_aux.h"
@@ -1125,6 +1126,9 @@ static void dcn302_resource_destruct(struct resource_pool *pool)
 
        if (pool->dccg != NULL)
                dcn_dccg_destroy(&pool->dccg);
+
+       if (pool->oem_device != NULL)
+               link_destroy_ddc_service(&pool->oem_device);
 }
 
 static void dcn302_destroy_resource_pool(struct resource_pool **pool)
@@ -1216,6 +1220,7 @@ static bool dcn302_resource_construct(
        int i;
        struct dc_context *ctx = dc->ctx;
        struct irq_service_init_data init_data;
+       struct ddc_service_init_data ddc_init_data = {0};
 
        ctx->dc_bios->regs = &bios_regs;
 
@@ -1497,6 +1502,17 @@ static bool dcn302_resource_construct(
 
        dc->cap_funcs = cap_funcs;
 
+       if (dc->ctx->dc_bios->fw_info.oem_i2c_present) {
+               ddc_init_data.ctx = dc->ctx;
+               ddc_init_data.link = NULL;
+               ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
+               ddc_init_data.id.enum_id = 0;
+               ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
+               pool->oem_device = link_create_ddc_service(&ddc_init_data);
+       } else {
+               pool->oem_device = NULL;
+       }
+
        return true;
 
 create_fail:
index c14d35894b2e574db8dd6b9090d0eab0d7ad3369..31e2120641681dabfdd8a9f13841b0a70797521a 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "dcn10/dcn10_resource.h"
 
-#include "dc_link_ddc.h"
+#include "link.h"
 
 #include "dce/dce_abm.h"
 #include "dce/dce_audio.h"
@@ -1054,7 +1054,7 @@ static void dcn303_resource_destruct(struct resource_pool *pool)
                dcn_dccg_destroy(&pool->dccg);
 
        if (pool->oem_device != NULL)
-               dal_ddc_service_destroy(&pool->oem_device);
+               link_destroy_ddc_service(&pool->oem_device);
 }
 
 static void dcn303_destroy_resource_pool(struct resource_pool **pool)
@@ -1421,7 +1421,7 @@ static bool dcn303_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->oem_device = dal_ddc_service_create(&ddc_init_data);
+               pool->oem_device = link_create_ddc_service(&ddc_init_data);
        } else {
                pool->oem_device = NULL;
        }
index ab70ebd8f223d8aa43e7f7160aedb16a535ce08f..275e78c06dee14a95be67c852e324791d1e427ae 100644 (file)
@@ -30,7 +30,6 @@
 #include "link_encoder.h"
 #include "dcn31_dio_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 
 #include "gpio_service_interface.h"
index 076969d928afaa6720060ddde44e71b26e542150..501388014855c5a1f830b6a830d9f6eed9bf3224 100644 (file)
@@ -31,7 +31,6 @@
 #include "dcn31/dcn31_dio_link_encoder.h"
 #include "dcn32_dio_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 #include "link_enc_cfg.h"
 
index dfecdf3e25e93869f798575495c66e9d74a5a7e2..47dc96acdacb2a3d7b258c14c41cecb986de7115 100644 (file)
@@ -69,7 +69,7 @@
 #include "dml/display_mode_vba.h"
 #include "dcn32/dcn32_dccg.h"
 #include "dcn10/dcn10_resource.h"
-#include "dc_link_ddc.h"
+#include "link.h"
 #include "dcn31/dcn31_panel_cntl.h"
 
 #include "dcn30/dcn30_dwb.h"
@@ -1508,7 +1508,7 @@ static void dcn32_resource_destruct(struct dcn32_resource_pool *pool)
                dcn_dccg_destroy(&pool->base.dccg);
 
        if (pool->base.oem_device != NULL)
-               dal_ddc_service_destroy(&pool->base.oem_device);
+               link_destroy_ddc_service(&pool->base.oem_device);
 }
 
 
@@ -2450,7 +2450,7 @@ static bool dcn32_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
+               pool->base.oem_device = link_create_ddc_service(&ddc_init_data);
        } else {
                pool->base.oem_device = NULL;
        }
index fa9b6603cfd37e4d890a831d61d8c2707bc40b29..13be5f06d987926aeb6694c52628748975923c03 100644 (file)
@@ -31,7 +31,6 @@
 #include "dcn321_dio_link_encoder.h"
 #include "dcn31/dcn31_dio_link_encoder.h"
 #include "stream_encoder.h"
-#include "i2caux_interface.h"
 #include "dc_bios_types.h"
 
 #include "gpio_service_interface.h"
index 62e400e90b56c47f883992cd5581cca9957083ff..260d71ca020568db11f28735fa0608c160daf18a 100644 (file)
@@ -73,7 +73,7 @@
 #include "dml/display_mode_vba.h"
 #include "dcn32/dcn32_dccg.h"
 #include "dcn10/dcn10_resource.h"
-#include "dc_link_ddc.h"
+#include "link.h"
 #include "dcn31/dcn31_panel_cntl.h"
 
 #include "dcn30/dcn30_dwb.h"
@@ -1493,7 +1493,7 @@ static void dcn321_resource_destruct(struct dcn321_resource_pool *pool)
                dcn_dccg_destroy(&pool->base.dccg);
 
        if (pool->base.oem_device != NULL)
-               dal_ddc_service_destroy(&pool->base.oem_device);
+               link_destroy_ddc_service(&pool->base.oem_device);
 }
 
 
@@ -1991,7 +1991,7 @@ static bool dcn321_resource_construct(
                ddc_init_data.id.id = dc->ctx->dc_bios->fw_info.oem_i2c_obj_id;
                ddc_init_data.id.enum_id = 0;
                ddc_init_data.id.type = OBJECT_TYPE_GENERIC;
-               pool->base.oem_device = dal_ddc_service_create(&ddc_init_data);
+               pool->base.oem_device = link_create_ddc_service(&ddc_init_data);
        } else {
                pool->base.oem_device = NULL;
        }
index 4233955e3c47b45af3443c548d9f6d3e9275fd33..6c4b47f90d499e5f35c05637a93cbec5fcdf7803 100644 (file)
 #include "dm_services.h"
 #include "dm_helpers.h"
 #include "include/hdcp_types.h"
-#include "include/i2caux_interface.h"
 #include "include/signal_types.h"
 #include "core_types.h"
-#include "dc_link_ddc.h"
+#include "link.h"
 #include "link_hwss.h"
 #include "inc/link_dpcd.h"
 
diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_ddc.h
deleted file mode 100644 (file)
index 95fb61d..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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_DDC_SERVICE_H__
-#define __DAL_DDC_SERVICE_H__
-
-#include "include/ddc_service_types.h"
-#include "include/i2caux_interface.h"
-
-#define EDID_SEGMENT_SIZE 256
-
-/* Address range from 0x00 to 0x1F.*/
-#define DP_ADAPTOR_TYPE2_SIZE 0x20
-#define DP_ADAPTOR_TYPE2_REG_ID 0x10
-#define DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK 0x1D
-/* Identifies adaptor as Dual-mode adaptor */
-#define DP_ADAPTOR_TYPE2_ID 0xA0
-/* MHz*/
-#define DP_ADAPTOR_TYPE2_MAX_TMDS_CLK 600
-/* MHz*/
-#define DP_ADAPTOR_TYPE2_MIN_TMDS_CLK 25
-/* kHZ*/
-#define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000
-/* kHZ*/
-#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000
-
-#define DDC_I2C_COMMAND_ENGINE I2C_COMMAND_ENGINE_SW
-
-struct ddc_service;
-struct graphics_object_id;
-enum ddc_result;
-struct av_sync_data;
-struct dp_receiver_id_info;
-
-struct i2c_payloads;
-struct aux_payloads;
-enum aux_return_code_type;
-
-void dal_ddc_i2c_payloads_add(
-               struct i2c_payloads *payloads,
-               uint32_t address,
-               uint32_t len,
-               uint8_t *data,
-               bool write);
-
-struct ddc_service_init_data {
-       struct graphics_object_id id;
-       struct dc_context *ctx;
-       struct dc_link *link;
-       bool is_dpia_link;
-};
-
-struct ddc_service *dal_ddc_service_create(
-               struct ddc_service_init_data *ddc_init_data);
-
-void dal_ddc_service_destroy(struct ddc_service **ddc);
-
-enum ddc_service_type dal_ddc_service_get_type(struct ddc_service *ddc);
-
-void dal_ddc_service_set_transaction_type(
-               struct ddc_service *ddc,
-               enum ddc_transaction_type type);
-
-bool dal_ddc_service_is_in_aux_transaction_mode(struct ddc_service *ddc);
-
-void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
-               struct ddc_service *ddc,
-               struct display_sink_capability *sink_cap);
-
-bool dal_ddc_service_query_ddc_data(
-               struct ddc_service *ddc,
-               uint32_t address,
-               uint8_t *write_buf,
-               uint32_t write_size,
-               uint8_t *read_buf,
-               uint32_t read_size);
-
-bool dal_ddc_submit_aux_command(struct ddc_service *ddc,
-               struct aux_payload *payload);
-
-int dc_link_aux_transfer_raw(struct ddc_service *ddc,
-               struct aux_payload *payload,
-               enum aux_return_code_type *operation_result);
-
-bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
-               struct aux_payload *payload);
-
-bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc,
-               uint32_t timeout);
-
-void dal_ddc_service_write_scdc_data(
-               struct ddc_service *ddc_service,
-               uint32_t pix_clk,
-               bool lte_340_scramble);
-
-void dal_ddc_service_read_scdc_data(
-               struct ddc_service *ddc_service);
-
-void ddc_service_set_dongle_type(struct ddc_service *ddc,
-               enum display_dongle_type dongle_type);
-
-void dal_ddc_service_set_ddc_pin(
-               struct ddc_service *ddc_service,
-               struct ddc *ddc);
-
-struct ddc *dal_ddc_service_get_ddc_pin(struct ddc_service *ddc_service);
-
-uint32_t get_defer_delay(struct ddc_service *ddc);
-
-#endif /* __DAL_DDC_SERVICE_H__ */
-
index 2ae630bf2aee48484ac5c1499b3e792225084888..7254182b7c721075f10d53f36d8679bbe7594bcc 100644 (file)
@@ -27,7 +27,6 @@
 #define __DAL_AUX_ENGINE_H__
 
 #include "dc_ddc_types.h"
-#include "include/i2caux_interface.h"
 
 enum aux_return_code_type;
 
@@ -81,7 +80,12 @@ enum i2c_default_speed {
        I2CAUX_DEFAULT_I2C_SW_SPEED = 50
 };
 
-union aux_config;
+union aux_config {
+       struct {
+               uint32_t ALLOW_AUX_WHEN_HPD_LOW:1;
+       } bits;
+       uint32_t raw;
+};
 
 struct aux_engine {
        uint32_t inst;
index 51ddf7a34d9875a765c29a7cc0a8096d739b77ec..8774d3a39f05da57a56a18982bab9933387e200b 100644 (file)
@@ -44,4 +44,41 @@ struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
                struct graphics_object_id link_id,
                struct gpio_service *gpio_service);
 
+struct ddc_service_init_data {
+       struct graphics_object_id id;
+       struct dc_context *ctx;
+       struct dc_link *link;
+       bool is_dpia_link;
+};
+
+struct ddc_service *link_create_ddc_service(
+               struct ddc_service_init_data *ddc_init_data);
+
+void link_destroy_ddc_service(struct ddc_service **ddc);
+
+bool link_is_in_aux_transaction_mode(struct ddc_service *ddc);
+
+bool link_query_ddc_data(
+               struct ddc_service *ddc,
+               uint32_t address,
+               uint8_t *write_buf,
+               uint32_t write_size,
+               uint8_t *read_buf,
+               uint32_t read_size);
+
+
+/* Attempt to submit an aux payload, retrying on timeouts, defers, and busy
+ * states as outlined in the DP spec.  Returns true if the request was
+ * successful.
+ *
+ * NOTE: The function requires explicit mutex on DM side in order to prevent
+ * potential race condition. DC components should call the dpcd read/write
+ * function in dm_helpers in order to access dpcd safely
+ */
+bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc,
+               struct aux_payload *payload);
+
+uint32_t link_get_aux_defer_delay(struct ddc_service *ddc);
+
+
 #endif /* __DC_LINK_HPD_H__ */
index 835a2febf2db295c3315ebe4b5b5350a4be26b35..d1b1bb3c53525e2638322e733dfdcf016a45716e 100644 (file)
@@ -24,7 +24,7 @@
 # PHY, HPD, DDC and etc).
 
 LINK = link_hwss_dio.o link_hwss_dpia.o link_hwss_hpo_dp.o link_dp_trace.o \
-link_hpd.o
+link_hpd.o link_ddc.o
 
 AMD_DAL_LINK = $(addprefix $(AMDDALPATH)/dc/link/,$(LINK))
 
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_ddc.c b/drivers/gpu/drm/amd/display/dc/link/link_ddc.c
new file mode 100644 (file)
index 0000000..5269125
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ * 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
+ *
+ */
+
+/* FILE POLICY AND INTENDED USAGE:
+ *
+ * This file implements generic display communication protocols such as i2c, aux
+ * and scdc. The file should not contain any specific applications of these
+ * protocols such as display capability query, detection, or handshaking such as
+ * link training.
+ */
+#include "link_ddc.h"
+#include "vector.h"
+#include "dce/dce_aux.h"
+#include "dal_asic_id.h"
+#include "link_dpcd.h"
+#include "dm_helpers.h"
+#include "atomfirmware.h"
+
+#define DC_LOGGER_INIT(logger)
+
+static const uint8_t DP_VGA_DONGLE_BRANCH_DEV_NAME[] = "DpVga";
+/* DP to Dual link DVI converter */
+static const uint8_t DP_DVI_CONVERTER_ID_4[] = "m2DVIa";
+static const uint8_t DP_DVI_CONVERTER_ID_5[] = "3393N2";
+
+struct i2c_payloads {
+       struct vector payloads;
+};
+
+struct aux_payloads {
+       struct vector payloads;
+};
+
+static bool dal_ddc_i2c_payloads_create(
+               struct dc_context *ctx,
+               struct i2c_payloads *payloads,
+               uint32_t count)
+{
+       if (dal_vector_construct(
+               &payloads->payloads, ctx, count, sizeof(struct i2c_payload)))
+               return true;
+
+       return false;
+}
+
+static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p)
+{
+       return (struct i2c_payload *)p->payloads.container;
+}
+
+static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p)
+{
+       return p->payloads.count;
+}
+
+#define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+static void i2c_payloads_add(
+       struct i2c_payloads *payloads,
+       uint32_t address,
+       uint32_t len,
+       uint8_t *data,
+       bool write)
+{
+       uint32_t payload_size = EDID_SEGMENT_SIZE;
+       uint32_t pos;
+
+       for (pos = 0; pos < len; pos += payload_size) {
+               struct i2c_payload payload = {
+                       .write = write,
+                       .address = address,
+                       .length = DDC_MIN(payload_size, len - pos),
+                       .data = data + pos };
+               dal_vector_append(&payloads->payloads, &payload);
+       }
+
+}
+
+static void ddc_service_construct(
+       struct ddc_service *ddc_service,
+       struct ddc_service_init_data *init_data)
+{
+       enum connector_id connector_id =
+               dal_graphics_object_id_get_connector_id(init_data->id);
+
+       struct gpio_service *gpio_service = init_data->ctx->gpio_service;
+       struct graphics_object_i2c_info i2c_info;
+       struct gpio_ddc_hw_info hw_info;
+       struct dc_bios *dcb = init_data->ctx->dc_bios;
+
+       ddc_service->link = init_data->link;
+       ddc_service->ctx = init_data->ctx;
+
+       if (init_data->is_dpia_link ||
+           dcb->funcs->get_i2c_info(dcb, init_data->id, &i2c_info) != BP_RESULT_OK) {
+               ddc_service->ddc_pin = NULL;
+       } else {
+               DC_LOGGER_INIT(ddc_service->ctx->logger);
+               DC_LOG_DC("BIOS object table - i2c_line: %d", i2c_info.i2c_line);
+               DC_LOG_DC("BIOS object table - i2c_engine_id: %d", i2c_info.i2c_engine_id);
+
+               hw_info.ddc_channel = i2c_info.i2c_line;
+               if (ddc_service->link != NULL)
+                       hw_info.hw_supported = i2c_info.i2c_hw_assist;
+               else
+                       hw_info.hw_supported = false;
+
+               ddc_service->ddc_pin = dal_gpio_create_ddc(
+                       gpio_service,
+                       i2c_info.gpio_info.clk_a_register_index,
+                       1 << i2c_info.gpio_info.clk_a_shift,
+                       &hw_info);
+       }
+
+       ddc_service->flags.EDID_QUERY_DONE_ONCE = false;
+       ddc_service->flags.FORCE_READ_REPEATED_START = false;
+       ddc_service->flags.EDID_STRESS_READ = false;
+
+       ddc_service->flags.IS_INTERNAL_DISPLAY =
+               connector_id == CONNECTOR_ID_EDP ||
+               connector_id == CONNECTOR_ID_LVDS;
+
+       ddc_service->wa.raw = 0;
+}
+
+struct ddc_service *link_create_ddc_service(
+       struct ddc_service_init_data *init_data)
+{
+       struct ddc_service *ddc_service;
+
+       ddc_service = kzalloc(sizeof(struct ddc_service), GFP_KERNEL);
+
+       if (!ddc_service)
+               return NULL;
+
+       ddc_service_construct(ddc_service, init_data);
+       return ddc_service;
+}
+
+static void ddc_service_destruct(struct ddc_service *ddc)
+{
+       if (ddc->ddc_pin)
+               dal_gpio_destroy_ddc(&ddc->ddc_pin);
+}
+
+void link_destroy_ddc_service(struct ddc_service **ddc)
+{
+       if (!ddc || !*ddc) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+       ddc_service_destruct(*ddc);
+       kfree(*ddc);
+       *ddc = NULL;
+}
+
+void set_ddc_transaction_type(
+       struct ddc_service *ddc,
+       enum ddc_transaction_type type)
+{
+       ddc->transaction_type = type;
+}
+
+bool link_is_in_aux_transaction_mode(struct ddc_service *ddc)
+{
+       switch (ddc->transaction_type) {
+       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX:
+       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER:
+       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_RETRY_DEFER:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
+
+void set_dongle_type(struct ddc_service *ddc,
+               enum display_dongle_type dongle_type)
+{
+       ddc->dongle_type = dongle_type;
+}
+
+static uint32_t defer_delay_converter_wa(
+       struct ddc_service *ddc,
+       uint32_t defer_delay)
+{
+       struct dc_link *link = ddc->link;
+
+       if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER &&
+               link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 &&
+               (link->dpcd_caps.branch_fw_revision[0] < 0x01 ||
+                               (link->dpcd_caps.branch_fw_revision[0] == 0x01 &&
+                               link->dpcd_caps.branch_fw_revision[1] < 0x40)) &&
+               !memcmp(link->dpcd_caps.branch_dev_name,
+                   DP_VGA_DONGLE_BRANCH_DEV_NAME,
+                       sizeof(link->dpcd_caps.branch_dev_name)))
+
+               return defer_delay > DPVGA_DONGLE_AUX_DEFER_WA_DELAY ?
+                       defer_delay : DPVGA_DONGLE_AUX_DEFER_WA_DELAY;
+
+       if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_0080E1 &&
+           !memcmp(link->dpcd_caps.branch_dev_name,
+                   DP_DVI_CONVERTER_ID_4,
+                   sizeof(link->dpcd_caps.branch_dev_name)))
+               return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY ?
+                       defer_delay : I2C_OVER_AUX_DEFER_WA_DELAY;
+       if (link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_006037 &&
+           !memcmp(link->dpcd_caps.branch_dev_name,
+                   DP_DVI_CONVERTER_ID_5,
+                   sizeof(link->dpcd_caps.branch_dev_name)))
+               return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY_1MS ?
+                       I2C_OVER_AUX_DEFER_WA_DELAY_1MS : defer_delay;
+
+       return defer_delay;
+}
+
+#define DP_TRANSLATOR_DELAY 5
+
+uint32_t link_get_aux_defer_delay(struct ddc_service *ddc)
+{
+       uint32_t defer_delay = 0;
+
+       switch (ddc->transaction_type) {
+       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX:
+               if ((DISPLAY_DONGLE_DP_VGA_CONVERTER == ddc->dongle_type) ||
+                       (DISPLAY_DONGLE_DP_DVI_CONVERTER == ddc->dongle_type) ||
+                       (DISPLAY_DONGLE_DP_HDMI_CONVERTER ==
+                               ddc->dongle_type)) {
+
+                       defer_delay = DP_TRANSLATOR_DELAY;
+
+                       defer_delay =
+                               defer_delay_converter_wa(ddc, defer_delay);
+
+               } else /*sink has a delay different from an Active Converter*/
+                       defer_delay = 0;
+               break;
+       case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER:
+               defer_delay = DP_TRANSLATOR_DELAY;
+               break;
+       default:
+               break;
+       }
+       return defer_delay;
+}
+
+static bool submit_aux_command(struct ddc_service *ddc,
+               struct aux_payload *payload)
+{
+       uint32_t retrieved = 0;
+       bool ret = false;
+
+       if (!ddc)
+               return false;
+
+       if (!payload)
+               return false;
+
+       do {
+               struct aux_payload current_payload;
+               bool is_end_of_payload = (retrieved + DEFAULT_AUX_MAX_DATA_SIZE) >=
+                               payload->length;
+               uint32_t payload_length = is_end_of_payload ?
+                               payload->length - retrieved : DEFAULT_AUX_MAX_DATA_SIZE;
+
+               current_payload.address = payload->address;
+               current_payload.data = &payload->data[retrieved];
+               current_payload.defer_delay = payload->defer_delay;
+               current_payload.i2c_over_aux = payload->i2c_over_aux;
+               current_payload.length = payload_length;
+               /* set mot (middle of transaction) to false if it is the last payload */
+               current_payload.mot = is_end_of_payload ? payload->mot:true;
+               current_payload.write_status_update = false;
+               current_payload.reply = payload->reply;
+               current_payload.write = payload->write;
+
+               ret = link_aux_transfer_with_retries_no_mutex(ddc, &current_payload);
+
+               retrieved += payload_length;
+       } while (retrieved < payload->length && ret == true);
+
+       return ret;
+}
+
+bool link_query_ddc_data(
+       struct ddc_service *ddc,
+       uint32_t address,
+       uint8_t *write_buf,
+       uint32_t write_size,
+       uint8_t *read_buf,
+       uint32_t read_size)
+{
+       bool success = true;
+       uint32_t payload_size =
+               link_is_in_aux_transaction_mode(ddc) ?
+                       DEFAULT_AUX_MAX_DATA_SIZE : EDID_SEGMENT_SIZE;
+
+       uint32_t write_payloads =
+               (write_size + payload_size - 1) / payload_size;
+
+       uint32_t read_payloads =
+               (read_size + payload_size - 1) / payload_size;
+
+       uint32_t payloads_num = write_payloads + read_payloads;
+
+       if (!payloads_num)
+               return false;
+
+       if (link_is_in_aux_transaction_mode(ddc)) {
+               struct aux_payload payload;
+
+               payload.i2c_over_aux = true;
+               payload.address = address;
+               payload.reply = NULL;
+               payload.defer_delay = link_get_aux_defer_delay(ddc);
+               payload.write_status_update = false;
+
+               if (write_size != 0) {
+                       payload.write = true;
+                       /* should not set mot (middle of transaction) to 0
+                        * if there are pending read payloads
+                        */
+                       payload.mot = !(read_size == 0);
+                       payload.length = write_size;
+                       payload.data = write_buf;
+
+                       success = submit_aux_command(ddc, &payload);
+               }
+
+               if (read_size != 0 && success) {
+                       payload.write = false;
+                       /* should set mot (middle of transaction) to 0
+                        * since it is the last payload to send
+                        */
+                       payload.mot = false;
+                       payload.length = read_size;
+                       payload.data = read_buf;
+
+                       success = submit_aux_command(ddc, &payload);
+               }
+       } else {
+               struct i2c_command command = {0};
+               struct i2c_payloads payloads;
+
+               if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num))
+                       return false;
+
+               command.payloads = dal_ddc_i2c_payloads_get(&payloads);
+               command.number_of_payloads = 0;
+               command.engine = DDC_I2C_COMMAND_ENGINE;
+               command.speed = ddc->ctx->dc->caps.i2c_speed_in_khz;
+
+               i2c_payloads_add(
+                       &payloads, address, write_size, write_buf, true);
+
+               i2c_payloads_add(
+                       &payloads, address, read_size, read_buf, false);
+
+               command.number_of_payloads =
+                       dal_ddc_i2c_payloads_get_count(&payloads);
+
+               success = dm_helpers_submit_i2c(
+                               ddc->ctx,
+                               ddc->link,
+                               &command);
+
+               dal_vector_destruct(&payloads.payloads);
+       }
+
+       return success;
+}
+
+int dc_link_aux_transfer_raw(struct ddc_service *ddc,
+               struct aux_payload *payload,
+               enum aux_return_code_type *operation_result)
+{
+       if (ddc->ctx->dc->debug.enable_dmub_aux_for_legacy_ddc ||
+           !ddc->ddc_pin) {
+               return dce_aux_transfer_dmub_raw(ddc, payload, operation_result);
+       } else {
+               return dce_aux_transfer_raw(ddc, payload, operation_result);
+       }
+}
+
+bool link_aux_transfer_with_retries_no_mutex(struct ddc_service *ddc,
+               struct aux_payload *payload)
+{
+       return dce_aux_transfer_with_retries(ddc, payload);
+}
+
+
+bool try_to_configure_aux_timeout(struct ddc_service *ddc,
+               uint32_t timeout)
+{
+       bool result = false;
+       struct ddc *ddc_pin = ddc->ddc_pin;
+
+       if ((ddc->link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
+                       !ddc->link->dc->debug.disable_fixed_vs_aux_timeout_wa &&
+                       ASICREV_IS_YELLOW_CARP(ddc->ctx->asic_id.hw_internal_rev)) {
+               /* Fixed VS workaround for AUX timeout */
+               const uint32_t fixed_vs_address = 0xF004F;
+               const uint8_t fixed_vs_data[4] = {0x1, 0x22, 0x63, 0xc};
+
+               core_link_write_dpcd(ddc->link,
+                               fixed_vs_address,
+                               fixed_vs_data,
+                               sizeof(fixed_vs_data));
+
+               timeout = 3072;
+       }
+
+       /* Do not try to access nonexistent DDC pin. */
+       if (ddc->link->ep_type != DISPLAY_ENDPOINT_PHY)
+               return true;
+
+       if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) {
+               ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout);
+               result = true;
+       }
+
+       return result;
+}
+
+struct ddc *get_ddc_pin(struct ddc_service *ddc_service)
+{
+       return ddc_service->ddc_pin;
+}
+
+void write_scdc_data(struct ddc_service *ddc_service,
+               uint32_t pix_clk,
+               bool lte_340_scramble)
+{
+       bool over_340_mhz = pix_clk > 340000 ? 1 : 0;
+       uint8_t slave_address = HDMI_SCDC_ADDRESS;
+       uint8_t offset = HDMI_SCDC_SINK_VERSION;
+       uint8_t sink_version = 0;
+       uint8_t write_buffer[2] = {0};
+       /*Lower than 340 Scramble bit from SCDC caps*/
+
+       if (ddc_service->link->local_sink &&
+               ddc_service->link->local_sink->edid_caps.panel_patch.skip_scdc_overwrite)
+               return;
+
+       link_query_ddc_data(ddc_service, slave_address, &offset,
+                       sizeof(offset), &sink_version, sizeof(sink_version));
+       if (sink_version == 1) {
+               /*Source Version = 1*/
+               write_buffer[0] = HDMI_SCDC_SOURCE_VERSION;
+               write_buffer[1] = 1;
+               link_query_ddc_data(ddc_service, slave_address,
+                               write_buffer, sizeof(write_buffer), NULL, 0);
+               /*Read Request from SCDC caps*/
+       }
+       write_buffer[0] = HDMI_SCDC_TMDS_CONFIG;
+
+       if (over_340_mhz) {
+               write_buffer[1] = 3;
+       } else if (lte_340_scramble) {
+               write_buffer[1] = 1;
+       } else {
+               write_buffer[1] = 0;
+       }
+       link_query_ddc_data(ddc_service, slave_address, write_buffer,
+                       sizeof(write_buffer), NULL, 0);
+}
+
+void read_scdc_data(struct ddc_service *ddc_service)
+{
+       uint8_t slave_address = HDMI_SCDC_ADDRESS;
+       uint8_t offset = HDMI_SCDC_TMDS_CONFIG;
+       uint8_t tmds_config = 0;
+
+       if (ddc_service->link->local_sink &&
+               ddc_service->link->local_sink->edid_caps.panel_patch.skip_scdc_overwrite)
+               return;
+
+       link_query_ddc_data(ddc_service, slave_address, &offset,
+                       sizeof(offset), &tmds_config, sizeof(tmds_config));
+       if (tmds_config & 0x1) {
+               union hdmi_scdc_status_flags_data status_data = {0};
+               uint8_t scramble_status = 0;
+
+               offset = HDMI_SCDC_SCRAMBLER_STATUS;
+               link_query_ddc_data(ddc_service, slave_address,
+                               &offset, sizeof(offset), &scramble_status,
+                               sizeof(scramble_status));
+               offset = HDMI_SCDC_STATUS_FLAGS;
+               link_query_ddc_data(ddc_service, slave_address,
+                               &offset, sizeof(offset), &status_data.byte,
+                               sizeof(status_data.byte));
+       }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/link/link_ddc.h b/drivers/gpu/drm/amd/display/dc/link/link_ddc.h
new file mode 100644 (file)
index 0000000..71a342d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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_DDC_SERVICE_H__
+#define __DAL_DDC_SERVICE_H__
+
+#include "link.h"
+
+#define AUX_POWER_UP_WA_DELAY 500
+#define I2C_OVER_AUX_DEFER_WA_DELAY 70
+#define DPVGA_DONGLE_AUX_DEFER_WA_DELAY 40
+#define I2C_OVER_AUX_DEFER_WA_DELAY_1MS 1
+
+#define EDID_SEGMENT_SIZE 256
+
+void set_ddc_transaction_type(
+               struct ddc_service *ddc,
+               enum ddc_transaction_type type);
+
+bool try_to_configure_aux_timeout(struct ddc_service *ddc,
+               uint32_t timeout);
+
+void write_scdc_data(
+               struct ddc_service *ddc_service,
+               uint32_t pix_clk,
+               bool lte_340_scramble);
+
+void read_scdc_data(
+               struct ddc_service *ddc_service);
+
+void set_dongle_type(struct ddc_service *ddc,
+               enum display_dongle_type dongle_type);
+
+struct ddc *get_ddc_pin(struct ddc_service *ddc_service);
+
+#endif /* __DAL_DDC_SERVICE_H__ */
+
diff --git a/drivers/gpu/drm/amd/display/include/i2caux_interface.h b/drivers/gpu/drm/amd/display/include/i2caux_interface.h
deleted file mode 100644 (file)
index 418fbf8..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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_I2CAUX_INTERFACE_H__
-#define __DAL_I2CAUX_INTERFACE_H__
-
-#include "dc_types.h"
-#include "gpio_service_interface.h"
-
-
-#define DEFAULT_AUX_MAX_DATA_SIZE 16
-#define AUX_MAX_DEFER_WRITE_RETRY 20
-
-struct aux_payload {
-       /* set following flag to read/write I2C data,
-        * reset it to read/write DPCD data */
-       bool i2c_over_aux;
-       /* set following flag to write data,
-        * reset it to read data */
-       bool write;
-       bool mot;
-       bool write_status_update;
-
-       uint32_t address;
-       uint32_t length;
-       uint8_t *data;
-       /*
-        * used to return the reply type of the transaction
-        * ignored if NULL
-        */
-       uint8_t *reply;
-       /* expressed in milliseconds
-        * zero means "use default value"
-        */
-       uint32_t defer_delay;
-
-};
-
-struct aux_command {
-       struct aux_payload *payloads;
-       uint8_t number_of_payloads;
-
-       /* expressed in milliseconds
-        * zero means "use default value" */
-       uint32_t defer_delay;
-
-       /* zero means "use default value" */
-       uint32_t max_defer_write_retry;
-
-       enum i2c_mot_mode mot;
-};
-
-union aux_config {
-       struct {
-               uint32_t ALLOW_AUX_WHEN_HPD_LOW:1;
-       } bits;
-       uint32_t raw;
-};
-
-#endif