]> git.ipfire.org Git - thirdparty/kernel/stable.git/blobdiff - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
Merge branch 'drm-next-5.1' of git://people.freedesktop.org/~agd5f/linux into drm...
[thirdparty/kernel/stable.git] / drivers / gpu / drm / amd / display / amdgpu_dm / amdgpu_dm_mst_types.c
index 1b0d209d836764ee16c4b9159100a52a6753f7b2..f51d52eb52e6d23f269cb3d7fa6745fb677bc002 100644 (file)
@@ -35,6 +35,8 @@
 
 #include "dc_link_ddc.h"
 
+#include "i2caux_interface.h"
+
 /* #define TRACE_DPCD */
 
 #ifdef TRACE_DPCD
@@ -81,80 +83,24 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
                                  struct drm_dp_aux_msg *msg)
 {
        ssize_t result = 0;
-       enum i2caux_transaction_action action;
-       enum aux_transaction_type type;
+       struct aux_payload payload;
 
        if (WARN_ON(msg->size > 16))
                return -E2BIG;
 
-       switch (msg->request & ~DP_AUX_I2C_MOT) {
-       case DP_AUX_NATIVE_READ:
-               type = AUX_TRANSACTION_TYPE_DP;
-               action = I2CAUX_TRANSACTION_ACTION_DP_READ;
-
-               result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
-                                             msg->address,
-                                             &msg->reply,
-                                             msg->buffer,
-                                             msg->size,
-                                             type,
-                                             action);
-               break;
-       case DP_AUX_NATIVE_WRITE:
-               type = AUX_TRANSACTION_TYPE_DP;
-               action = I2CAUX_TRANSACTION_ACTION_DP_WRITE;
-
-               dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
-                                    msg->address,
-                                    &msg->reply,
-                                    msg->buffer,
-                                    msg->size,
-                                    type,
-                                    action);
-               result = msg->size;
-               break;
-       case DP_AUX_I2C_READ:
-               type = AUX_TRANSACTION_TYPE_I2C;
-               if (msg->request & DP_AUX_I2C_MOT)
-                       action = I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT;
-               else
-                       action = I2CAUX_TRANSACTION_ACTION_I2C_READ;
-
-               result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
-                                             msg->address,
-                                             &msg->reply,
-                                             msg->buffer,
-                                             msg->size,
-                                             type,
-                                             action);
-               break;
-       case DP_AUX_I2C_WRITE:
-               type = AUX_TRANSACTION_TYPE_I2C;
-               if (msg->request & DP_AUX_I2C_MOT)
-                       action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT;
-               else
-                       action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
-
-               dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service,
-                                    msg->address,
-                                    &msg->reply,
-                                    msg->buffer,
-                                    msg->size,
-                                    type,
-                                    action);
-               result = msg->size;
-               break;
-       default:
-               return -EINVAL;
-       }
+       payload.address = msg->address;
+       payload.data = msg->buffer;
+       payload.length = msg->size;
+       payload.reply = &msg->reply;
+       payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0;
+       payload.write = (msg->request & DP_AUX_I2C_READ) == 0;
+       payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0;
+       payload.defer_delay = 0;
 
-#ifdef TRACE_DPCD
-       log_dpcd(msg->request,
-                msg->address,
-                msg->buffer,
-                msg->size,
-                r == DDC_RESULT_SUCESSFULL);
-#endif
+       result = dc_link_aux_transfer(TO_DM_AUX(aux)->ddc_service, &payload);
+
+       if (payload.write)
+               result = msg->size;
 
        if (result < 0) /* DC doesn't know about kernel error codes */
                result = -EIO;
@@ -191,6 +137,7 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
        drm_encoder_cleanup(&amdgpu_encoder->base);
        kfree(amdgpu_encoder);
        drm_connector_cleanup(connector);
+       drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port);
        kfree(amdgpu_dm_connector);
 }
 
@@ -227,6 +174,11 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
                aconnector->edid = edid;
        }
 
+       if (aconnector->dc_sink && aconnector->dc_sink->sink_signal == SIGNAL_TYPE_VIRTUAL) {
+               dc_sink_release(aconnector->dc_sink);
+               aconnector->dc_sink = NULL;
+       }
+
        if (!aconnector->dc_sink) {
                struct dc_sink *dc_sink;
                struct dc_sink_init_data init_params = {
@@ -363,7 +315,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
        amdgpu_dm_connector_funcs_reset(connector);
 
        DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n",
-                       aconnector, connector->base.id, aconnector->mst_port);
+                aconnector, connector->base.id, aconnector->mst_port);
+
+       drm_dp_mst_get_port_malloc(port);
 
        DRM_DEBUG_KMS(":%d\n", connector->base.id);
 
@@ -379,12 +333,12 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
 
        DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n",
-                               aconnector, connector->base.id, aconnector->mst_port);
+                aconnector, connector->base.id, aconnector->mst_port);
 
-       aconnector->port = NULL;
        if (aconnector->dc_sink) {
                amdgpu_dm_update_freesync_caps(connector, NULL);
-               dc_link_remove_remote_sink(aconnector->dc_link, aconnector->dc_sink);
+               dc_link_remove_remote_sink(aconnector->dc_link,
+                                          aconnector->dc_sink);
                dc_sink_release(aconnector->dc_sink);
                aconnector->dc_sink = NULL;
        }
@@ -395,14 +349,6 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
        drm_connector_put(connector);
 }
 
-static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
-{
-       struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr);
-       struct drm_device *dev = master->base.dev;
-
-       drm_kms_helper_hotplug_event(dev);
-}
-
 static void dm_dp_mst_register_connector(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
@@ -419,7 +365,6 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector)
 static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
        .add_connector = dm_dp_add_mst_connector,
        .destroy_connector = dm_dp_destroy_mst_connector,
-       .hotplug = dm_dp_mst_hotplug,
        .register_connector = dm_dp_mst_register_connector
 };