drm/amd/display: Add DCN3 DIO
[linux-2.6-block.git] / drivers / gpu / drm / amd / display / dc / core / dc_link.c
index 67c5342cf89a381683fb2f53cd1f891bfc2ae1c8..cb5491fb326c110dcbe613b40c0dff434838b16f 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/slab.h>
 
 #include "dm_services.h"
-#include "atom.h"
+#include "atomfirmware.h"
 #include "dm_helpers.h"
 #include "dc.h"
 #include "grph_object_id.h"
@@ -46,7 +46,7 @@
 #include "dmcu.h"
 #include "hw/clk_mgr.h"
 #include "dce/dmub_psr.h"
-#include "dmub/inc/dmub_cmd_dal.h"
+#include "dmub/dmub_srv.h"
 #include "inc/hw/panel_cntl.h"
 
 #define DC_LOGGER_INIT(logger)
@@ -521,11 +521,11 @@ static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *lin
 }
 
 #if defined(CONFIG_DRM_AMD_DC_HDCP)
-bool dc_link_is_hdcp14(struct dc_link *link)
+bool dc_link_is_hdcp14(struct dc_link *link, enum signal_type signal)
 {
        bool ret = false;
 
-       switch (link->connector_signal) {
+       switch (signal) {
        case SIGNAL_TYPE_DISPLAY_PORT:
        case SIGNAL_TYPE_DISPLAY_PORT_MST:
                ret = link->hdcp_caps.bcaps.bits.HDCP_CAPABLE;
@@ -545,11 +545,11 @@ bool dc_link_is_hdcp14(struct dc_link *link)
        return ret;
 }
 
-bool dc_link_is_hdcp22(struct dc_link *link)
+bool dc_link_is_hdcp22(struct dc_link *link, enum signal_type signal)
 {
        bool ret = false;
 
-       switch (link->connector_signal) {
+       switch (signal) {
        case SIGNAL_TYPE_DISPLAY_PORT:
        case SIGNAL_TYPE_DISPLAY_PORT_MST:
                ret = (link->hdcp_caps.bcaps.bits.HDCP_CAPABLE &&
@@ -691,10 +691,9 @@ static bool detect_dp(struct dc_link *link,
        if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
                sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
 
-               dpcd_set_source_specific_data(link);
-
                if (!detect_dp_sink_caps(link))
                        return false;
+               dpcd_set_source_specific_data(link);
 
                if (is_mst_supported(link)) {
                        sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
@@ -1552,7 +1551,7 @@ static bool dc_link_construct(struct dc_link *link,
         */
        program_hpd_filter(link);
 
-       link->psr_settings.psr_version = PSR_VERSION_UNSUPPORTED;
+       link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
 
        return true;
 device_tag_fail:
@@ -2504,59 +2503,56 @@ int dc_link_get_target_backlight_pwm(const struct dc_link *link)
        return (int) abm->funcs->get_target_backlight(abm);
 }
 
+static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link)
+{
+       int i;
+       struct dc *dc = link->ctx->dc;
+       struct pipe_ctx *pipe_ctx = NULL;
+
+       for (i = 0; i < MAX_PIPES; i++) {
+               if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
+                       if (dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) {
+                               pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
+                               break;
+                       }
+               }
+       }
+
+       return pipe_ctx;
+}
+
 bool dc_link_set_backlight_level(const struct dc_link *link,
                uint32_t backlight_pwm_u16_16,
                uint32_t frame_ramp)
 {
        struct dc  *dc = link->ctx->dc;
-       int i;
 
        DC_LOGGER_INIT(link->ctx->logger);
        DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n",
                        backlight_pwm_u16_16, backlight_pwm_u16_16);
 
        if (dc_is_embedded_signal(link->connector_signal)) {
-               struct pipe_ctx *pipe_ctx = NULL;
-
-               for (i = 0; i < MAX_PIPES; i++) {
-                       if (dc->current_state->res_ctx.pipe_ctx[i].stream) {
-                               if (dc->current_state->res_ctx.
-                                               pipe_ctx[i].stream->link
-                                               == link) {
-                                       pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
-
-                                       /* Disable brightness ramping when the display is blanked
-                                        * as it can hang the DMCU
-                                        */
-                                       if (dc->current_state->res_ctx.pipe_ctx[i].plane_state == NULL)
-                                               frame_ramp = 0;
-                               }
-                       }
-               }
+               struct pipe_ctx *pipe_ctx = get_pipe_from_link(link);
 
-               if (pipe_ctx == NULL)
+               if (pipe_ctx) {
+                       /* Disable brightness ramping when the display is blanked
+                        * as it can hang the DMCU
+                        */
+                       if (pipe_ctx->plane_state == NULL)
+                               frame_ramp = 0;
+               } else {
                        ASSERT(false);
+                       return false;
+               }
 
                dc->hwss.set_backlight_level(
                                pipe_ctx,
                                backlight_pwm_u16_16,
                                frame_ramp);
        }
-
        return true;
 }
 
-bool dc_link_set_abm_disable(const struct dc_link *link)
-{
-       struct abm *abm = get_abm_from_stream_res(link);
-       bool success = false;
-
-       if (abm)
-               success = abm->funcs->set_abm_immediate_disable(abm, link->panel_cntl->inst);
-
-       return success;
-}
-
 bool dc_link_set_psr_allow_active(struct dc_link *link, bool allow_active, bool wait)
 {
        struct dc  *dc = link->ctx->dc;
@@ -3137,6 +3133,11 @@ void core_link_enable_stream(
 
        pipe_ctx->stream->link->link_state_valid = true;
 
+#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
+               if (pipe_ctx->stream_res.tg->funcs->set_out_mux)
+                                       pipe_ctx->stream_res.tg->funcs->set_out_mux(pipe_ctx->stream_res.tg, OUT_MUX_DIO);
+#endif
+
        if (dc_is_dvi_signal(pipe_ctx->stream->signal))
                pipe_ctx->stream_res.stream_enc->funcs->dvi_set_stream_attribute(
                        pipe_ctx->stream_res.stream_enc,
@@ -3219,6 +3220,15 @@ void core_link_enable_stream(
                                        CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
                                        COLOR_DEPTH_UNDEFINED);
 
+               /* This second call is needed to reconfigure the DIG
+                * as a workaround for the incorrect value being applied
+                * from transmitter control.
+                */
+               if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
+                       stream->link->link_enc->funcs->setup(
+                               stream->link->link_enc,
+                               pipe_ctx->stream->signal);
+
                dc->hwss.enable_stream(pipe_ctx);
 
                /* Set DPS PPS SDP (AKA "info frames") */
@@ -3248,6 +3258,10 @@ void core_link_enable_stream(
                        dp_set_dsc_enable(pipe_ctx, true);
 
        }
+
+       if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
+               core_link_set_avmute(pipe_ctx, false);
+       }
 }
 
 void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
@@ -3260,6 +3274,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
                        dc_is_virtual_signal(pipe_ctx->stream->signal))
                return;
 
+       if (pipe_ctx->stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
+               core_link_set_avmute(pipe_ctx, true);
+       }
+
 #if defined(CONFIG_DRM_AMD_DC_HDCP)
        update_psp_stream_config(pipe_ctx, true);
 #endif