]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 20 May 2014 05:28:33 +0000 (14:28 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 20 May 2014 05:28:33 +0000 (14:28 +0900)
Pull drm/intel fixes from Dave Airlie:
 "Just some intel fixes.

  I have some radeon ones but I need to get some patches dropped from
  the pull req"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/i915: Increase WM memory latency values on SNB
  drm/i915: restore backlight precision when converting from ACPI
  drm/i915: Use the first mode if there is no preferred mode in the EDID
  drm/i915/dp: force eDP lane count to max available lanes on BDW
  drm/i915/vlv: reset VLV media force wake request register
  drm/i915/SDVO: For sysfs link put directory and target in correct order
  drm/i915: use lane count and link rate from VBT as minimums for eDP
  drm/i915: clean up VBT eDP link param decoding
  drm/i915: consider the source max DP lane count too

drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_uncore.c

index fa486c5fbb0250650b558632c6f63aa0ebf5bd63..aff4a113cda3c0cd724d3b4d13ce0fb8bbc48313 100644 (file)
@@ -560,47 +560,71 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
 
        dev_priv->vbt.edp_pps = *edp_pps;
 
-       dev_priv->vbt.edp_rate = edp_link_params->rate ? DP_LINK_BW_2_7 :
-               DP_LINK_BW_1_62;
+       switch (edp_link_params->rate) {
+       case EDP_RATE_1_62:
+               dev_priv->vbt.edp_rate = DP_LINK_BW_1_62;
+               break;
+       case EDP_RATE_2_7:
+               dev_priv->vbt.edp_rate = DP_LINK_BW_2_7;
+               break;
+       default:
+               DRM_DEBUG_KMS("VBT has unknown eDP link rate value %u\n",
+                             edp_link_params->rate);
+               break;
+       }
+
        switch (edp_link_params->lanes) {
-       case 0:
+       case EDP_LANE_1:
                dev_priv->vbt.edp_lanes = 1;
                break;
-       case 1:
+       case EDP_LANE_2:
                dev_priv->vbt.edp_lanes = 2;
                break;
-       case 3:
-       default:
+       case EDP_LANE_4:
                dev_priv->vbt.edp_lanes = 4;
                break;
+       default:
+               DRM_DEBUG_KMS("VBT has unknown eDP lane count value %u\n",
+                             edp_link_params->lanes);
+               break;
        }
+
        switch (edp_link_params->preemphasis) {
-       case 0:
+       case EDP_PREEMPHASIS_NONE:
                dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_0;
                break;
-       case 1:
+       case EDP_PREEMPHASIS_3_5dB:
                dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_3_5;
                break;
-       case 2:
+       case EDP_PREEMPHASIS_6dB:
                dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_6;
                break;
-       case 3:
+       case EDP_PREEMPHASIS_9_5dB:
                dev_priv->vbt.edp_preemphasis = DP_TRAIN_PRE_EMPHASIS_9_5;
                break;
+       default:
+               DRM_DEBUG_KMS("VBT has unknown eDP pre-emphasis value %u\n",
+                             edp_link_params->preemphasis);
+               break;
        }
+
        switch (edp_link_params->vswing) {
-       case 0:
+       case EDP_VSWING_0_4V:
                dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_400;
                break;
-       case 1:
+       case EDP_VSWING_0_6V:
                dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_600;
                break;
-       case 2:
+       case EDP_VSWING_0_8V:
                dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_800;
                break;
-       case 3:
+       case EDP_VSWING_1_2V:
                dev_priv->vbt.edp_vswing = DP_TRAIN_VOLTAGE_SWING_1200;
                break;
+       default:
+               DRM_DEBUG_KMS("VBT has unknown eDP voltage swing value %u\n",
+                             edp_link_params->vswing);
+               break;
        }
 }
 
index 5ca68aa9f237e0422350a537ce48075e3c23b8ae..2a00cb828d20c7549a7b00a6745c228998cc136b 100644 (file)
@@ -121,6 +121,22 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp)
        return max_link_bw;
 }
 
+static u8 intel_dp_max_lane_count(struct intel_dp *intel_dp)
+{
+       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+       struct drm_device *dev = intel_dig_port->base.base.dev;
+       u8 source_max, sink_max;
+
+       source_max = 4;
+       if (HAS_DDI(dev) && intel_dig_port->port == PORT_A &&
+           (intel_dig_port->saved_port_bits & DDI_A_4_LANES) == 0)
+               source_max = 2;
+
+       sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
+
+       return min(source_max, sink_max);
+}
+
 /*
  * The units on the numbers in the next two are... bizarre.  Examples will
  * make it clearer; this one parallels an example in the eDP spec.
@@ -171,7 +187,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
        }
 
        max_link_clock = drm_dp_bw_code_to_link_rate(intel_dp_max_link_bw(intel_dp));
-       max_lanes = drm_dp_max_lane_count(intel_dp->dpcd);
+       max_lanes = intel_dp_max_lane_count(intel_dp);
 
        max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
        mode_rate = intel_dp_link_required(target_clock, 18);
@@ -751,8 +767,10 @@ intel_dp_compute_config(struct intel_encoder *encoder,
        struct intel_crtc *intel_crtc = encoder->new_crtc;
        struct intel_connector *intel_connector = intel_dp->attached_connector;
        int lane_count, clock;
-       int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd);
+       int min_lane_count = 1;
+       int max_lane_count = intel_dp_max_lane_count(intel_dp);
        /* Conveniently, the link BW constants become indices with a shift...*/
+       int min_clock = 0;
        int max_clock = intel_dp_max_link_bw(intel_dp) >> 3;
        int bpp, mode_rate;
        static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 };
@@ -785,19 +803,38 @@ intel_dp_compute_config(struct intel_encoder *encoder,
        /* Walk through all bpp values. Luckily they're all nicely spaced with 2
         * bpc in between. */
        bpp = pipe_config->pipe_bpp;
-       if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp &&
-           dev_priv->vbt.edp_bpp < bpp) {
-               DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n",
-                             dev_priv->vbt.edp_bpp);
-               bpp = dev_priv->vbt.edp_bpp;
+       if (is_edp(intel_dp)) {
+               if (dev_priv->vbt.edp_bpp && dev_priv->vbt.edp_bpp < bpp) {
+                       DRM_DEBUG_KMS("clamping bpp for eDP panel to BIOS-provided %i\n",
+                                     dev_priv->vbt.edp_bpp);
+                       bpp = dev_priv->vbt.edp_bpp;
+               }
+
+               if (IS_BROADWELL(dev)) {
+                       /* Yes, it's an ugly hack. */
+                       min_lane_count = max_lane_count;
+                       DRM_DEBUG_KMS("forcing lane count to max (%u) on BDW\n",
+                                     min_lane_count);
+               } else if (dev_priv->vbt.edp_lanes) {
+                       min_lane_count = min(dev_priv->vbt.edp_lanes,
+                                            max_lane_count);
+                       DRM_DEBUG_KMS("using min %u lanes per VBT\n",
+                                     min_lane_count);
+               }
+
+               if (dev_priv->vbt.edp_rate) {
+                       min_clock = min(dev_priv->vbt.edp_rate >> 3, max_clock);
+                       DRM_DEBUG_KMS("using min %02x link bw per VBT\n",
+                                     bws[min_clock]);
+               }
        }
 
        for (; bpp >= 6*3; bpp -= 2*3) {
                mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
                                                   bpp);
 
-               for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
-                       for (clock = 0; clock <= max_clock; clock++) {
+               for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) {
+                       for (clock = min_clock; clock <= max_clock; clock++) {
                                link_clock = drm_dp_bw_code_to_link_rate(bws[clock]);
                                link_avail = intel_dp_max_data_rate(link_clock,
                                                                    lane_count);
index fce4a0d93c0b19b7d51f4d2578331b13aef51399..f73ba5e6b7a8d685b4530e16c6735c095c2aeb5f 100644 (file)
@@ -387,6 +387,15 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
                                                          height);
                }
 
+               /* No preferred mode marked by the EDID? Are there any modes? */
+               if (!modes[i] && !list_empty(&connector->modes)) {
+                       DRM_DEBUG_KMS("using first mode listed on connector %s\n",
+                                     drm_get_connector_name(connector));
+                       modes[i] = list_first_entry(&connector->modes,
+                                                   struct drm_display_mode,
+                                                   head);
+               }
+
                /* last resort: use current mode */
                if (!modes[i]) {
                        /*
index 0eead16aeda7404053de8c9885992b0904c1049c..cb8cfb7e09749938383c18a7eb6e2bc149823095 100644 (file)
@@ -492,6 +492,7 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
        enum pipe pipe = intel_get_pipe_from_connector(connector);
        u32 freq;
        unsigned long flags;
+       u64 n;
 
        if (!panel->backlight.present || pipe == INVALID_PIPE)
                return;
@@ -502,10 +503,9 @@ void intel_panel_set_backlight(struct intel_connector *connector, u32 level,
 
        /* scale to hardware max, but be careful to not overflow */
        freq = panel->backlight.max;
-       if (freq < max)
-               level = level * freq / max;
-       else
-               level = freq / max * level;
+       n = (u64)level * freq;
+       do_div(n, max);
+       level = n;
 
        panel->backlight.level = level;
        if (panel->backlight.device)
index 19e94c3edc1957d96b928fb23d696b393216fc42..d93dcf683e8c3695960ca93c92dce87a7823d3f2 100644 (file)
@@ -2095,6 +2095,43 @@ static void intel_print_wm_latency(struct drm_device *dev,
        }
 }
 
+static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv,
+                                   uint16_t wm[5], uint16_t min)
+{
+       int level, max_level = ilk_wm_max_level(dev_priv->dev);
+
+       if (wm[0] >= min)
+               return false;
+
+       wm[0] = max(wm[0], min);
+       for (level = 1; level <= max_level; level++)
+               wm[level] = max_t(uint16_t, wm[level], DIV_ROUND_UP(min, 5));
+
+       return true;
+}
+
+static void snb_wm_latency_quirk(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       bool changed;
+
+       /*
+        * The BIOS provided WM memory latency values are often
+        * inadequate for high resolution displays. Adjust them.
+        */
+       changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) |
+               ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) |
+               ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12);
+
+       if (!changed)
+               return;
+
+       DRM_DEBUG_KMS("WM latency values increased to avoid potential underruns\n");
+       intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency);
+       intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency);
+       intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
+}
+
 static void ilk_setup_wm_latency(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2112,6 +2149,9 @@ static void ilk_setup_wm_latency(struct drm_device *dev)
        intel_print_wm_latency(dev, "Primary", dev_priv->wm.pri_latency);
        intel_print_wm_latency(dev, "Sprite", dev_priv->wm.spr_latency);
        intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
+
+       if (IS_GEN6(dev))
+               snb_wm_latency_quirk(dev);
 }
 
 static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
index d27155adf5db2b039dee51b9aa0de25e60c8967e..46be00d66df3da3e74597ba9c02f0ac745741751 100644 (file)
@@ -2424,8 +2424,8 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
        if (ret < 0)
                goto err1;
 
-       ret = sysfs_create_link(&encoder->ddc.dev.kobj,
-                               &drm_connector->kdev->kobj,
+       ret = sysfs_create_link(&drm_connector->kdev->kobj,
+                               &encoder->ddc.dev.kobj,
                                encoder->ddc.dev.kobj.name);
        if (ret < 0)
                goto err2;
index f729dc71d5beb031599aca72f82c90ec946e2fe0..d0c75779d3f6f91e9cc98b0f1a853344783fdb48 100644 (file)
@@ -185,6 +185,8 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
 {
        __raw_i915_write32(dev_priv, FORCEWAKE_VLV,
                           _MASKED_BIT_DISABLE(0xffff));
+       __raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
+                          _MASKED_BIT_DISABLE(0xffff));
        /* something from same cacheline, but !FORCEWAKE_VLV */
        __raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
 }