drm/i915: Fix MST link rate handling
[linux-2.6-block.git] / drivers / gpu / drm / i915 / intel_dp_mst.c
index 7f8c6a66680a611c3aeff7171c8a1b0839daa8b9..7e6f12597a6cbc257c52aa677f9474d7b1d2ba5b 100644 (file)
 #include <drm/drmP.h>
 #include "i915_drv.h"
 #include "intel_drv.h"
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_edid.h>
 
 static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
-                                       struct intel_crtc_config *pipe_config)
+                                       struct intel_crtc_state *pipe_config)
 {
        struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
        struct intel_digital_port *intel_dig_port = intel_mst->primary;
        struct intel_dp *intel_dp = &intel_dig_port->dp;
        struct drm_device *dev = encoder->base.dev;
        int bpp;
-       int lane_count, slots;
-       struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
+       int lane_count, slots, rate;
+       struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
        struct intel_connector *found = NULL, *intel_connector;
        int mst_pbn;
 
@@ -51,13 +52,23 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
         * seem to suggest we should do otherwise.
         */
        lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
-       intel_dp->link_bw = intel_dp_max_link_bw(intel_dp);
+
+       rate = intel_dp_max_link_rate(intel_dp);
+
+       if (intel_dp->num_supported_rates) {
+               intel_dp->link_bw = 0;
+               intel_dp->rate_select = intel_dp_rate_select(intel_dp, rate);
+       } else {
+               intel_dp->link_bw = drm_dp_link_rate_to_bw_code(rate);
+               intel_dp->rate_select = 0;
+       }
+
        intel_dp->lane_count = lane_count;
 
        pipe_config->pipe_bpp = 24;
-       pipe_config->port_clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw);
+       pipe_config->port_clock = rate;
 
-       list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) {
+       for_each_intel_connector(dev, intel_connector) {
                if (intel_connector->new_encoder == encoder) {
                        found = intel_connector;
                        break;
@@ -139,7 +150,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
        struct drm_crtc *crtc = encoder->base.crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
-       list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) {
+       for_each_intel_connector(dev, intel_connector) {
                if (intel_connector->new_encoder == encoder) {
                        found = intel_connector;
                        break;
@@ -157,7 +168,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
        if (intel_dp->active_mst_links == 0) {
                enum port port = intel_ddi_get_encoder_port(encoder);
 
-               I915_WRITE(PORT_CLK_SEL(port), intel_crtc->config.ddi_pll_sel);
+               I915_WRITE(PORT_CLK_SEL(port),
+                          intel_crtc->config->ddi_pll_sel);
 
                intel_ddi_init_dp_buf_reg(&intel_dig_port->base);
 
@@ -170,7 +182,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder)
        }
 
        ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
-                                      intel_mst->port, intel_crtc->config.pbn, &slots);
+                                      intel_mst->port,
+                                      intel_crtc->config->pbn, &slots);
        if (ret == false) {
                DRM_ERROR("failed to allocate vcpi\n");
                return;
@@ -216,14 +229,14 @@ static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
 }
 
 static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
-                                       struct intel_crtc_config *pipe_config)
+                                       struct intel_crtc_state *pipe_config)
 {
        struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
        struct intel_digital_port *intel_dig_port = intel_mst->primary;
        struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
        struct drm_device *dev = encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
+       enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
        u32 temp, flags = 0;
 
        pipe_config->has_dp_encoder = true;
@@ -254,7 +267,7 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
        default:
                break;
        }
-       pipe_config->adjusted_mode.flags |= flags;
+       pipe_config->base.adjusted_mode.flags |= flags;
        intel_dp_get_m_n(crtc, pipe_config);
 
        intel_ddi_clock_get(&intel_dig_port->base, pipe_config);
@@ -311,7 +324,9 @@ static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
        .detect = intel_dp_mst_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = intel_dp_mst_set_property,
+       .atomic_get_property = intel_connector_atomic_get_property,
        .destroy = intel_dp_mst_connector_destroy,
+       .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
 static int intel_dp_mst_get_modes(struct drm_connector *connector)