]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel...
authorDave Airlie <airlied@redhat.com>
Tue, 29 May 2012 10:09:06 +0000 (11:09 +0100)
committerDave Airlie <airlied@redhat.com>
Tue, 29 May 2012 10:09:06 +0000 (11:09 +0100)
* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: tune down the noise of the RP irq limit fail
  drm/i915: Remove the error message for unbinding pinned buffers
  drm/i915: Limit page allocations to lowmem (dma32) for i965
  drm/i915: always use RPNSWREQ for turbo change requests
  drm/i915: reject doubleclocked cea modes on dp
  drm/i915: Adding TV Out Missing modes.
  drm/i915: wait for a vblank to pass after tv detect
  drm/i915: no lvds quirk for HP t5740e Thin Client
  drm/i915: enable vdd when switching off the eDP panel
  drm/i915: Fix PCH PLL assertions to not assume CRTC:PLL relationship
  drm/i915: Always update RPS interrupts thresholds along with frequency
  drm/i915: properly handle interlaced bit for sdvo dtd conversion
  drm/i915: fix module unload since error_state rework
  drm/i915: be more careful when returning -ENXIO in gmbus transfer

1  2 
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_sdvo.c

index c1e5c66553dfcff66892876f854f3e708d92ac93,465e775b8cdef29e6a82c3e71f561c0aeb6091e0..288d7b8f49ae48858a30c6ad1f9f7ce1d6d6e600
@@@ -35,7 -35,6 +35,7 @@@
  #include <linux/slab.h>
  #include <linux/swap.h>
  #include <linux/pci.h>
 +#include <linux/dma-buf.h>
  
  static __must_check int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj);
  static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj);
@@@ -539,14 -538,6 +539,14 @@@ i915_gem_pread_ioctl(struct drm_device 
                goto out;
        }
  
 +      /* prime objects have no backing filp to GEM pread/pwrite
 +       * pages from.
 +       */
 +      if (!obj->base.filp) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
        trace_i915_gem_object_pread(obj, args->offset, args->size);
  
        ret = i915_gem_shmem_pread(dev, obj, args, file);
@@@ -889,14 -880,6 +889,14 @@@ i915_gem_pwrite_ioctl(struct drm_devic
                goto out;
        }
  
 +      /* prime objects have no backing filp to GEM pread/pwrite
 +       * pages from.
 +       */
 +      if (!obj->base.filp) {
 +              ret = -EINVAL;
 +              goto out;
 +      }
 +
        trace_i915_gem_object_pwrite(obj, args->offset, args->size);
  
        ret = -EFAULT;
@@@ -1038,14 -1021,6 +1038,14 @@@ i915_gem_mmap_ioctl(struct drm_device *
        if (obj == NULL)
                return -ENOENT;
  
 +      /* prime objects have no backing filp to GEM mmap
 +       * pages from.
 +       */
 +      if (!obj->filp) {
 +              drm_gem_object_unreference_unlocked(obj);
 +              return -EINVAL;
 +      }
 +
        addr = vm_mmap(obj->filp, 0, args->size,
                       PROT_READ | PROT_WRITE, MAP_SHARED,
                       args->offset);
@@@ -1327,7 -1302,8 +1327,7 @@@ i915_gem_mmap_gtt_ioctl(struct drm_devi
        return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset);
  }
  
 -
 -static int
 +int
  i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
                              gfp_t gfpmask)
  {
        struct inode *inode;
        struct page *page;
  
 +      if (obj->pages || obj->sg_table)
 +              return 0;
 +
        /* Get the list of pages out of our struct file.  They'll be pinned
         * at this point until we release them.
         */
@@@ -1380,9 -1353,6 +1380,9 @@@ i915_gem_object_put_pages_gtt(struct dr
        int page_count = obj->base.size / PAGE_SIZE;
        int i;
  
 +      if (!obj->pages)
 +              return;
 +
        BUG_ON(obj->madv == __I915_MADV_PURGED);
  
        if (i915_gem_object_needs_bit17_swizzle(obj))
@@@ -2063,10 -2033,8 +2063,8 @@@ i915_gem_object_unbind(struct drm_i915_
        if (obj->gtt_space == NULL)
                return 0;
  
-       if (obj->pin_count != 0) {
-               DRM_ERROR("Attempting to unbind pinned buffer\n");
-               return -EINVAL;
-       }
+       if (obj->pin_count)
+               return -EBUSY;
  
        ret = i915_gem_object_finish_gpu(obj);
        if (ret)
@@@ -3293,6 -3261,7 +3291,7 @@@ struct drm_i915_gem_object *i915_gem_al
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj;
        struct address_space *mapping;
+       u32 mask;
  
        obj = kzalloc(sizeof(*obj), GFP_KERNEL);
        if (obj == NULL)
                return NULL;
        }
  
+       mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
+       if (IS_CRESTLINE(dev) || IS_BROADWATER(dev)) {
+               /* 965gm cannot relocate objects above 4GiB. */
+               mask &= ~__GFP_HIGHMEM;
+               mask |= __GFP_DMA32;
+       }
        mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
-       mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE);
+       mapping_set_gfp_mask(mapping, mask);
  
        i915_gem_info_add_obj(dev_priv, size);
  
@@@ -3357,9 -3333,6 +3363,9 @@@ void i915_gem_free_object(struct drm_ge
  
        trace_i915_gem_object_destroy(obj);
  
 +      if (gem_obj->import_attach)
 +              drm_prime_gem_destroy(gem_obj, obj->sg_table);
 +
        if (obj->phys_obj)
                i915_gem_detach_phys_object(dev, obj);
  
index ee61ad1e642b06848f537fb6000b3d83c3bf1be1,67ed819220a4ce009fe9b645ea49b4f61c01fb72..9147894209061dd69c12ddc9bde72f904ebae3ac
@@@ -910,9 -910,10 +910,10 @@@ static void assert_pll(struct drm_i915_
  
  /* For ILK+ */
  static void assert_pch_pll(struct drm_i915_private *dev_priv,
-                          struct intel_crtc *intel_crtc, bool state)
+                          struct intel_pch_pll *pll,
+                          struct intel_crtc *crtc,
+                          bool state)
  {
-       int reg;
        u32 val;
        bool cur_state;
  
                return;
        }
  
-       if (!intel_crtc->pch_pll) {
-               WARN(1, "asserting PCH PLL enabled with no PLL\n");
+       if (WARN (!pll,
+                 "asserting PCH PLL %s with no PLL\n", state_string(state)))
                return;
-       }
  
-       if (HAS_PCH_CPT(dev_priv->dev)) {
+       val = I915_READ(pll->pll_reg);
+       cur_state = !!(val & DPLL_VCO_ENABLE);
+       WARN(cur_state != state,
+            "PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n",
+            pll->pll_reg, state_string(state), state_string(cur_state), val);
+       /* Make sure the selected PLL is correctly attached to the transcoder */
+       if (crtc && HAS_PCH_CPT(dev_priv->dev)) {
                u32 pch_dpll;
  
                pch_dpll = I915_READ(PCH_DPLL_SEL);
-               /* Make sure the selected PLL is enabled to the transcoder */
-               WARN(!((pch_dpll >> (4 * intel_crtc->pipe)) & 8),
-                    "transcoder %d PLL not enabled\n", intel_crtc->pipe);
+               cur_state = pll->pll_reg == _PCH_DPLL_B;
+               if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state,
+                         "PLL[%d] not attached to this transcoder %d: %08x\n",
+                         cur_state, crtc->pipe, pch_dpll)) {
+                       cur_state = !!(val >> (4*crtc->pipe + 3));
+                       WARN(cur_state != state,
+                            "PLL[%d] not %s on this transcoder %d: %08x\n",
+                            pll->pll_reg == _PCH_DPLL_B,
+                            state_string(state),
+                            crtc->pipe,
+                            val);
+               }
        }
-       reg = intel_crtc->pch_pll->pll_reg;
-       val = I915_READ(reg);
-       cur_state = !!(val & DPLL_VCO_ENABLE);
-       WARN(cur_state != state,
-            "PCH PLL state assertion failure (expected %s, current %s)\n",
-            state_string(state), state_string(cur_state));
  }
- #define assert_pch_pll_enabled(d, p) assert_pch_pll(d, p, true)
- #define assert_pch_pll_disabled(d, p) assert_pch_pll(d, p, false)
+ #define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true)
+ #define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false)
  
  static void assert_fdi_tx(struct drm_i915_private *dev_priv,
                          enum pipe pipe, bool state)
@@@ -1424,7 -1432,7 +1432,7 @@@ static void intel_enable_pch_pll(struc
        assert_pch_refclk_enabled(dev_priv);
  
        if (pll->active++ && pll->on) {
-               assert_pch_pll_enabled(dev_priv, intel_crtc);
+               assert_pch_pll_enabled(dev_priv, pll, NULL);
                return;
        }
  
@@@ -1460,12 -1468,12 +1468,12 @@@ static void intel_disable_pch_pll(struc
                      intel_crtc->base.base.id);
  
        if (WARN_ON(pll->active == 0)) {
-               assert_pch_pll_disabled(dev_priv, intel_crtc);
+               assert_pch_pll_disabled(dev_priv, pll, NULL);
                return;
        }
  
        if (--pll->active) {
-               assert_pch_pll_enabled(dev_priv, intel_crtc);
+               assert_pch_pll_enabled(dev_priv, pll, NULL);
                return;
        }
  
@@@ -1495,7 -1503,9 +1503,9 @@@ static void intel_enable_transcoder(str
        BUG_ON(dev_priv->info->gen < 5);
  
        /* Make sure PCH DPLL is enabled */
-       assert_pch_pll_enabled(dev_priv, to_intel_crtc(crtc));
+       assert_pch_pll_enabled(dev_priv,
+                              to_intel_crtc(crtc)->pch_pll,
+                              to_intel_crtc(crtc));
  
        /* FDI must be feeding us bits for PCH ports */
        assert_fdi_tx_enabled(dev_priv, pipe);
@@@ -6941,7 -6951,7 +6951,7 @@@ void intel_modeset_init(struct drm_devi
        dev->mode_config.preferred_depth = 24;
        dev->mode_config.prefer_shadow = 1;
  
 -      dev->mode_config.funcs = (void *)&intel_mode_funcs;
 +      dev->mode_config.funcs = &intel_mode_funcs;
  
        intel_init_quirks(dev);
  
index 71c7096e386950f5fc8f2fbad253dc80cd764e16,eb57ec7b36f44c0dc8c55e3db65da7997a17ede9..296cfc201a81ea9a0017abfb0e97eee7eaf8dc18
@@@ -266,6 -266,9 +266,9 @@@ intel_dp_mode_valid(struct drm_connecto
        if (mode->clock < 10000)
                return MODE_CLOCK_LOW;
  
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+               return MODE_H_ILLEGAL;
        return MODE_OK;
  }
  
@@@ -702,6 -705,9 +705,9 @@@ intel_dp_mode_fixup(struct drm_encoder 
                mode->clock = intel_dp->panel_fixed_mode->clock;
        }
  
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+               return false;
        DRM_DEBUG_KMS("DP link computation with max lane count %i "
                      "max bw %02x pixel clock %iKHz\n",
                      max_lane_count, bws[max_clock], mode->clock);
@@@ -1154,11 -1160,10 +1160,10 @@@ static void ironlake_edp_panel_off(stru
  
        DRM_DEBUG_KMS("Turn eDP power off\n");
  
-       WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n");
-       ironlake_panel_vdd_off_sync(intel_dp); /* finish any pending work */
+       WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
  
        pp = ironlake_get_pp_control(dev_priv);
-       pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
+       pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE);
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
  
@@@ -1266,18 -1271,16 +1271,16 @@@ static void intel_dp_prepare(struct drm
  {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
  
+       /* Make sure the panel is off before trying to change the mode. But also
+        * ensure that we have vdd while we switch off the panel. */
+       ironlake_edp_panel_vdd_on(intel_dp);
        ironlake_edp_backlight_off(intel_dp);
        ironlake_edp_panel_off(intel_dp);
  
-       /* Wake up the sink first */
-       ironlake_edp_panel_vdd_on(intel_dp);
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
        intel_dp_link_down(intel_dp);
        ironlake_edp_panel_vdd_off(intel_dp, false);
-       /* Make sure the panel is off before trying to
-        * change the mode
-        */
  }
  
  static void intel_dp_commit(struct drm_encoder *encoder)
@@@ -1309,10 -1312,11 +1312,11 @@@ intel_dp_dpms(struct drm_encoder *encod
        uint32_t dp_reg = I915_READ(intel_dp->output_reg);
  
        if (mode != DRM_MODE_DPMS_ON) {
+               /* Switching the panel off requires vdd. */
+               ironlake_edp_panel_vdd_on(intel_dp);
                ironlake_edp_backlight_off(intel_dp);
                ironlake_edp_panel_off(intel_dp);
  
-               ironlake_edp_panel_vdd_on(intel_dp);
                intel_dp_sink_dpms(intel_dp, mode);
                intel_dp_link_down(intel_dp);
                ironlake_edp_panel_vdd_off(intel_dp, false);
@@@ -1961,23 -1965,6 +1965,23 @@@ intel_dp_get_dpcd(struct intel_dp *inte
        return false;
  }
  
 +static void
 +intel_dp_probe_oui(struct intel_dp *intel_dp)
 +{
 +      u8 buf[3];
 +
 +      if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
 +              return;
 +
 +      if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3))
 +              DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
 +                            buf[0], buf[1], buf[2]);
 +
 +      if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3))
 +              DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
 +                            buf[0], buf[1], buf[2]);
 +}
 +
  static bool
  intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector)
  {
@@@ -2161,8 -2148,6 +2165,8 @@@ intel_dp_detect(struct drm_connector *c
        if (status != connector_status_connected)
                return status;
  
 +      intel_dp_probe_oui(intel_dp);
 +
        if (intel_dp->force_audio != HDMI_AUDIO_AUTO) {
                intel_dp->has_audio = (intel_dp->force_audio == HDMI_AUDIO_ON);
        } else {
index a949b73880c8302db5f3b255429cf24ab12fea8d,a6582079134f373a1823fc116ffd7369499030fb..b6a9d45fc3c69d4b5be7e8c6f93490636b6049c2
@@@ -783,10 -783,12 +783,12 @@@ static void intel_sdvo_get_dtd_from_mod
                ((v_sync_len & 0x30) >> 4);
  
        dtd->part2.dtd_flags = 0x18;
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+               dtd->part2.dtd_flags |= DTD_FLAG_INTERLACE;
        if (mode->flags & DRM_MODE_FLAG_PHSYNC)
-               dtd->part2.dtd_flags |= 0x2;
+               dtd->part2.dtd_flags |= DTD_FLAG_HSYNC_POSITIVE;
        if (mode->flags & DRM_MODE_FLAG_PVSYNC)
-               dtd->part2.dtd_flags |= 0x4;
+               dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE;
  
        dtd->part2.sdvo_flags = 0;
        dtd->part2.v_sync_off_high = v_sync_offset & 0xc0;
@@@ -820,9 -822,11 +822,11 @@@ static void intel_sdvo_get_mode_from_dt
        mode->clock = dtd->part1.clock * 10;
  
        mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
-       if (dtd->part2.dtd_flags & 0x2)
+       if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE)
+               mode->flags |= DRM_MODE_FLAG_INTERLACE;
+       if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
                mode->flags |= DRM_MODE_FLAG_PHSYNC;
-       if (dtd->part2.dtd_flags & 0x4)
+       if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
                mode->flags |= DRM_MODE_FLAG_PVSYNC;
  }
  
@@@ -1241,14 -1245,8 +1245,14 @@@ static bool intel_sdvo_get_capabilities
  
  static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo)
  {
 +      struct drm_device *dev = intel_sdvo->base.base.dev;
        u8 response[2];
  
 +      /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
 +       * on the line. */
 +      if (IS_I945G(dev) || IS_I945GM(dev))
 +              return false;
 +
        return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
                                    &response, 2) && response[0];
  }