Merge tag 'drm-intel-next-2018-02-21' of git://anongit.freedesktop.org/drm/drm-intel...
authorDave Airlie <airlied@redhat.com>
Thu, 1 Mar 2018 04:07:22 +0000 (14:07 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 1 Mar 2018 04:07:22 +0000 (14:07 +1000)
Driver Changes:

- Lift alpha_support protection from Cannonlake (Rodrigo)
* Meaning the driver should mostly work for the hardware we had
  at our disposal when testing
* Used to be preliminary_hw_support
- Add missing Cannonlake PCI device ID of 0x5A4C (Rodrigo)
- Cannonlake port register fix (Mahesh)

- Fix Dell Venue 8 Pro black screen after modeset (Hans)
- Fix for always returning zero out-fence from execbuf (Daniele)
- Fix HDMI audio when no no relevant video output is active (Jani)
- Fix memleak of VBT data on driver_unload (Hans)

- Fix for KASAN found locking issue (Maarten)
- RCU barrier consolidation to improve igt/gem_sync/idle (Chris)
- Optimizations to IRQ handlers (Chris)
- vblank tracking improvements (64-bit resolution, PM) (Dhinakaran)
- Pipe select bit corrections (Ville)
- Reduce runtime computed device_info fields (Chris)
- Tune down some WARN_ONs to GEM_BUG_ON now that CI has good coverage (Chris)
- A bunch of kerneldoc warning fixes (Chris)

* tag 'drm-intel-next-2018-02-21' of git://anongit.freedesktop.org/drm/drm-intel: (113 commits)
  drm/i915: Update DRIVER_DATE to 20180221
  drm/i915/fbc: Use PLANE_HAS_FENCE to determine if the plane is fenced
  drm/i915/fbdev: Use the PLANE_HAS_FENCE flags from the time of pinning
  drm/i915: Move the policy for placement of the GGTT vma into the caller
  drm/i915: Also check view->type for a normal GGTT view
  drm/i915: Drop WaDoubleCursorLP3Latency:ivb
  drm/i915: Set the primary plane pipe select bits on gen4
  drm/i915: Don't set cursor pipe select bits on g4x+
  drm/i915: Assert that we don't overflow frontbuffer tracking bits
  drm/i915: Track number of pending freed objects
  drm/i915/: Initialise trans_min for skl_compute_transition_wm()
  drm/i915: Clear the in-use marker on execbuf failure
  drm/i915: Prune gen8_gt_irq_handler
  drm/i915: Track GT interrupt handling using the master iir
  drm/i915: Remove WARN_ONCE for failing to pm_runtime_if_in_use
  drm: intel_dpio_phy: fix kernel-doc comments at nested struct
  drm/i915: Release connector iterator on a digital port conflict.
  drm/i915/execlists: Remove too early assert
  drm/i915: Assert that we always complete a submission to guc/execlists
  drm: move read_domains and write_domain into i915
  ...

83 files changed:
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/drm_plane.c
drivers/gpu/drm/drm_vblank.c
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/dvo_ivch.c
drivers/gpu/drm/i915/gvt/dmabuf.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_clflush.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_context.h
drivers/gpu/drm/i915/i915_gem_dmabuf.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_fence_reg.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gem_internal.c
drivers/gpu/drm/i915/i915_gem_object.h
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/i915_gem_stolen.c
drivers/gpu/drm/i915/i915_gem_userptr.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/i915_ioc32.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_oa_cflgt3.c
drivers/gpu/drm/i915/i915_oa_cnl.c
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_pmu.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_syncmap.c
drivers/gpu/drm/i915/intel_atomic.c
drivers/gpu/drm/i915/intel_atomic_plane.c
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_breadcrumbs.c
drivers/gpu/drm/i915/intel_cdclk.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_device_info.c
drivers/gpu/drm/i915/intel_device_info.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dpio_phy.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_fbc.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_guc_submission.c
drivers/gpu/drm/i915/intel_huc.c
drivers/gpu/drm/i915/intel_lpe_audio.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_mocs.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_psr.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/i915/intel_uc_fw.c
drivers/gpu/drm/i915/intel_uncore.c
drivers/gpu/drm/i915/intel_uncore.h
drivers/gpu/drm/i915/selftests/huge_gem_object.c
drivers/gpu/drm/i915/selftests/huge_pages.c
drivers/gpu/drm/i915/selftests/i915_gem_context.c
drivers/gpu/drm/i915/selftests/i915_gem_gtt.c
drivers/gpu/drm/i915/selftests/i915_gem_object.c
drivers/gpu/drm/i915/selftests/intel_guc.c
drivers/gpu/drm/i915/selftests/mock_gem_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/tegra/dc.c
include/drm/drm_atomic.h
include/drm/drm_gem.h
include/drm/drm_vblank.h
include/drm/i915_pciids.h

index 1eb0861c91476a29aaa244555aeb867ae8f8b41d..93f700ab1bfbfbd75b29757d9acbff329e88e898 100644 (file)
@@ -210,7 +210,7 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc,
        amdgpu_bo_unreserve(new_abo);
 
        work->base = base;
-       work->target_vblank = target - drm_crtc_vblank_count(crtc) +
+       work->target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) +
                amdgpu_get_vblank_counter_kms(dev, work->crtc_id);
 
        /* we borrow the event spin lock for protecting flip_wrok */
index 84f6fe9a448bb85f9d17e1e61b8a568d459b2e97..246fff33c7bf556e9ca228b0ad4025aa84a582c3 100644 (file)
@@ -3842,7 +3842,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
 
 
        /* Prepare wait for target vblank early - before the fence-waits */
-       target_vblank = target - drm_crtc_vblank_count(crtc) +
+       target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) +
                        amdgpu_get_vblank_counter_kms(crtc->dev, acrtc->crtc_id);
 
        /* TODO This might fail and hence better not used, wait
@@ -3988,7 +3988,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
                        amdgpu_dm_do_flip(
                                crtc,
                                fb,
-                               drm_crtc_vblank_count(crtc) + *wait_for_vblank,
+                               (uint32_t)drm_crtc_vblank_count(crtc) + *wait_for_vblank,
                                dm_state->context);
                }
 
index 22b54663b6e7e6aa69f81accda0971ceb698af17..09de6ecb396867052ee3455d4916dc2559e233d4 100644 (file)
@@ -948,7 +948,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
                if (r)
                        return r;
 
-               current_vblank = drm_crtc_vblank_count(crtc);
+               current_vblank = (u32)drm_crtc_vblank_count(crtc);
 
                switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) {
                case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE:
index 32d9bcf5be7f3f28367f7751b633f9b20fbb5ddc..c781cb426bf172c4d8cf081e0cb7e232ae5482ad 100644 (file)
@@ -271,7 +271,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
        store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
 }
 
-static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
+static u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
 {
        struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
 
@@ -292,11 +292,11 @@ static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
  * This is mostly useful for hardware that can obtain the scanout position, but
  * doesn't have a hardware frame counter.
  */
-u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
+u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
        unsigned int pipe = drm_crtc_index(crtc);
-       u32 vblank;
+       u64 vblank;
        unsigned long flags;
 
        WARN_ONCE(drm_debug & DRM_UT_VBL && !dev->driver->get_vblank_timestamp,
@@ -347,23 +347,25 @@ void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
        spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
 
        /*
-        * Only disable vblank interrupts if they're enabled. This avoids
-        * calling the ->disable_vblank() operation in atomic context with the
-        * hardware potentially runtime suspended.
+        * Update vblank count and disable vblank interrupts only if the
+        * interrupts were enabled. This avoids calling the ->disable_vblank()
+        * operation in atomic context with the hardware potentially runtime
+        * suspended.
         */
-       if (vblank->enabled) {
-               __disable_vblank(dev, pipe);
-               vblank->enabled = false;
-       }
+       if (!vblank->enabled)
+               goto out;
 
        /*
-        * Always update the count and timestamp to maintain the
+        * Update the count and timestamp to maintain the
         * appearance that the counter has been ticking all along until
         * this time. This makes the count account for the entire time
         * between drm_crtc_vblank_on() and drm_crtc_vblank_off().
         */
        drm_update_vblank_count(dev, pipe, false);
+       __disable_vblank(dev, pipe);
+       vblank->enabled = false;
 
+out:
        spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
 }
 
@@ -1055,7 +1057,7 @@ void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
 {
        struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
        int ret;
-       u32 last;
+       u64 last;
 
        if (WARN_ON(pipe >= dev->num_crtcs))
                return;
@@ -1235,6 +1237,65 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_crtc_vblank_on);
 
+/**
+ * drm_vblank_restore - estimated vblanks using timestamps and update it.
+ *
+ * Power manamement features can cause frame counter resets between vblank
+ * disable and enable. Drivers can then use this function in their
+ * &drm_crtc_funcs.enable_vblank implementation to estimate the vblanks since
+ * the last &drm_crtc_funcs.disable_vblank.
+ *
+ * This function is the legacy version of drm_crtc_vblank_restore().
+ */
+void drm_vblank_restore(struct drm_device *dev, unsigned int pipe)
+{
+       ktime_t t_vblank;
+       struct drm_vblank_crtc *vblank;
+       int framedur_ns;
+       u64 diff_ns;
+       u32 cur_vblank, diff = 1;
+       int count = DRM_TIMESTAMP_MAXRETRIES;
+
+       if (WARN_ON(pipe >= dev->num_crtcs))
+               return;
+
+       assert_spin_locked(&dev->vbl_lock);
+       assert_spin_locked(&dev->vblank_time_lock);
+
+       vblank = &dev->vblank[pipe];
+       WARN_ONCE((drm_debug & DRM_UT_VBL) && !vblank->framedur_ns,
+                 "Cannot compute missed vblanks without frame duration\n");
+       framedur_ns = vblank->framedur_ns;
+
+       do {
+               cur_vblank = __get_vblank_counter(dev, pipe);
+               drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
+       } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
+
+       diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
+       if (framedur_ns)
+               diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
+
+
+       DRM_DEBUG_VBL("missed %d vblanks in %lld ns, frame duration=%d ns, hw_diff=%d\n",
+                     diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
+       store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
+}
+EXPORT_SYMBOL(drm_vblank_restore);
+
+/**
+ * drm_crtc_vblank_restore - estimate vblanks using timestamps and update it.
+ * Power manamement features can cause frame counter resets between vblank
+ * disable and enable. Drivers can then use this function in their
+ * &drm_crtc_funcs.enable_vblank implementation to estimate the vblanks since
+ * the last &drm_crtc_funcs.disable_vblank.
+ */
+void drm_crtc_vblank_restore(struct drm_crtc *crtc)
+{
+       drm_vblank_restore(crtc->dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_restore);
+
 static void drm_legacy_vblank_pre_modeset(struct drm_device *dev,
                                          unsigned int pipe)
 {
index 3bddd8a068066d2ef23c2e1c7de11514c1bf93c1..f55cc028b2eb522895bf31e07fb03cab6a957f8c 100644 (file)
@@ -17,6 +17,7 @@ subdir-ccflags-y += $(call cc-disable-warning, unused-parameter)
 subdir-ccflags-y += $(call cc-disable-warning, type-limits)
 subdir-ccflags-y += $(call cc-disable-warning, missing-field-initializers)
 subdir-ccflags-y += $(call cc-disable-warning, implicit-fallthrough)
+subdir-ccflags-y += $(call cc-disable-warning, unused-but-set-variable)
 subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror
 
 # Fine grained warnings disable
index 4950b82f5b490e104fd08aae492a4df1faa6b036..c73aff163908af1933ea0d2d0afb4f42145ccbaf 100644 (file)
  * This must not be set while VR01_DVO_BYPASS_ENABLE is set.
  */
 # define VR01_LCD_ENABLE               (1 << 2)
-/** Enables the DVO repeater. */
+/* Enables the DVO repeater. */
 # define VR01_DVO_BYPASS_ENABLE                (1 << 1)
-/** Enables the DVO clock */
+/* Enables the DVO clock */
 # define VR01_DVO_ENABLE               (1 << 0)
-/** Enable dithering for 18bpp panels. Not documented. */
+/* Enable dithering for 18bpp panels. Not documented. */
 # define VR01_DITHER_ENABLE             (1 << 4)
 
 /*
  * LCD Interface Format
  */
 #define VR10           0x10
-/** Enables LVDS output instead of CMOS */
+/* Enables LVDS output instead of CMOS */
 # define VR10_LVDS_ENABLE              (1 << 4)
-/** Enables 18-bit LVDS output. */
+/* Enables 18-bit LVDS output. */
 # define VR10_INTERFACE_1X18           (0 << 2)
-/** Enables 24-bit LVDS or CMOS output */
+/* Enables 24-bit LVDS or CMOS output */
 # define VR10_INTERFACE_1X24           (1 << 2)
-/** Enables 2x18-bit LVDS or CMOS output. */
+/* Enables 2x18-bit LVDS or CMOS output. */
 # define VR10_INTERFACE_2X18           (2 << 2)
-/** Enables 2x24-bit LVDS output */
+/* Enables 2x24-bit LVDS output */
 # define VR10_INTERFACE_2X24           (3 << 2)
-/** Mask that defines the depth of the pipeline */
+/* Mask that defines the depth of the pipeline */
 # define VR10_INTERFACE_DEPTH_MASK      (3 << 2)
 
 /*
@@ -97,7 +97,7 @@
  * Panel power down status
  */
 #define VR30           0x30
-/** Read only bit indicating that the panel is not in a safe poweroff state. */
+/* Read only bit indicating that the panel is not in a safe poweroff state. */
 # define VR30_PANEL_ON                 (1 << 15)
 
 #define VR40           0x40
@@ -183,7 +183,7 @@ struct ivch_priv {
 
 
 static void ivch_dump_regs(struct intel_dvo_device *dvo);
-/**
+/*
  * Reads a register on the ivch.
  *
  * Each of the 256 registers are 16 bits long.
@@ -230,7 +230,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
        return false;
 }
 
-/** Writes a 16-bit register on the ivch */
+/* Writes a 16-bit register on the ivch */
 static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
 {
        struct ivch_priv *priv = dvo->dev_priv;
@@ -258,7 +258,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
        return false;
 }
 
-/** Probes the given bus and slave address for an ivch */
+/* Probes the given bus and slave address for an ivch */
 static bool ivch_init(struct intel_dvo_device *dvo,
                      struct i2c_adapter *adapter)
 {
@@ -338,7 +338,7 @@ static void ivch_reset(struct intel_dvo_device *dvo)
                ivch_write(dvo, backup_addresses[i], priv->reg_backup[i]);
 }
 
-/** Sets the power state of the panel connected to the ivch */
+/* Sets the power state of the panel connected to the ivch */
 static void ivch_dpms(struct intel_dvo_device *dvo, bool enable)
 {
        int i;
index 2fb7b34ef561efde785c1c13a6658b8b941c871a..9a471b0afb15367229887a7ff80dcac5b8c62f55 100644 (file)
@@ -162,8 +162,8 @@ static struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev,
                info->size << PAGE_SHIFT);
        i915_gem_object_init(obj, &intel_vgpu_gem_ops);
 
-       obj->base.read_domains = I915_GEM_DOMAIN_GTT;
-       obj->base.write_domain = 0;
+       obj->read_domains = I915_GEM_DOMAIN_GTT;
+       obj->write_domain = 0;
        if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
                unsigned int tiling_mode = 0;
                unsigned int stride = 0;
index 3849ded354e3337ae5146ac347388b5230b062bc..05b41045b8f9d11118a34f445f8263561e3970a2 100644 (file)
@@ -49,6 +49,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
 
        intel_device_info_dump_flags(info, &p);
        intel_device_info_dump_runtime(info, &p);
+       intel_driver_caps_print(&dev_priv->caps, &p);
 
        kernel_param_lock(THIS_MODULE);
        i915_params_dump(&i915_modparams, &p);
@@ -149,8 +150,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
                   get_global_flag(obj),
                   get_pin_mapped_flag(obj),
                   obj->base.size / 1024,
-                  obj->base.read_domains,
-                  obj->base.write_domain,
+                  obj->read_domains,
+                  obj->write_domain,
                   i915_cache_level_str(dev_priv, obj->cache_level),
                   obj->mm.dirty ? " dirty" : "",
                   obj->mm.madv == I915_MADV_DONTNEED ? " purgeable" : "");
@@ -1460,19 +1461,6 @@ static int gen6_drpc_info(struct seq_file *m)
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
        u32 gt_core_status, rcctl1, rc6vids = 0;
        u32 gen9_powergate_enable = 0, gen9_powergate_status = 0;
-       unsigned forcewake_count;
-       int count = 0;
-
-       forcewake_count = READ_ONCE(dev_priv->uncore.fw_domain[FW_DOMAIN_ID_RENDER].wake_count);
-       if (forcewake_count) {
-               seq_puts(m, "RC information inaccurate because somebody "
-                           "holds a forcewake reference \n");
-       } else {
-               /* NB: we cannot use forcewake, else we read the wrong values */
-               while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
-                       udelay(10);
-               seq_printf(m, "RC information accurate: %s\n", yesno(count < 51));
-       }
 
        gt_core_status = I915_READ_FW(GEN6_GT_CORE_STATUS);
        trace_i915_reg_rw(false, GEN6_GT_CORE_STATUS, gt_core_status, 4, true);
@@ -1483,9 +1471,12 @@ static int gen6_drpc_info(struct seq_file *m)
                gen9_powergate_status = I915_READ(GEN9_PWRGT_DOMAIN_STATUS);
        }
 
-       mutex_lock(&dev_priv->pcu_lock);
-       sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
-       mutex_unlock(&dev_priv->pcu_lock);
+       if (INTEL_GEN(dev_priv) <= 7) {
+               mutex_lock(&dev_priv->pcu_lock);
+               sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS,
+                                      &rc6vids);
+               mutex_unlock(&dev_priv->pcu_lock);
+       }
 
        seq_printf(m, "RC1e Enabled: %s\n",
                   yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
@@ -1541,12 +1532,15 @@ static int gen6_drpc_info(struct seq_file *m)
        print_rc6_res(m, "RC6+ residency since boot:", GEN6_GT_GFX_RC6p);
        print_rc6_res(m, "RC6++ residency since boot:", GEN6_GT_GFX_RC6pp);
 
-       seq_printf(m, "RC6   voltage: %dmV\n",
-                  GEN6_DECODE_RC6_VID(((rc6vids >> 0) & 0xff)));
-       seq_printf(m, "RC6+  voltage: %dmV\n",
-                  GEN6_DECODE_RC6_VID(((rc6vids >> 8) & 0xff)));
-       seq_printf(m, "RC6++ voltage: %dmV\n",
-                  GEN6_DECODE_RC6_VID(((rc6vids >> 16) & 0xff)));
+       if (INTEL_GEN(dev_priv) <= 7) {
+               seq_printf(m, "RC6   voltage: %dmV\n",
+                          GEN6_DECODE_RC6_VID(((rc6vids >> 0) & 0xff)));
+               seq_printf(m, "RC6+  voltage: %dmV\n",
+                          GEN6_DECODE_RC6_VID(((rc6vids >> 8) & 0xff)));
+               seq_printf(m, "RC6++ voltage: %dmV\n",
+                          GEN6_DECODE_RC6_VID(((rc6vids >> 16) & 0xff)));
+       }
+
        return i915_forcewake_domains(m, NULL);
 }
 
@@ -1599,7 +1593,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused)
                seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
 
        if (fbc->work.scheduled)
-               seq_printf(m, "FBC worker scheduled on vblank %u, now %llu\n",
+               seq_printf(m, "FBC worker scheduled on vblank %llu, now %llu\n",
                           fbc->work.scheduled_vblank,
                           drm_crtc_vblank_count(&fbc->crtc->base));
 
@@ -2338,7 +2332,6 @@ static int i915_guc_info(struct seq_file *m, void *data)
                return -ENODEV;
 
        GEM_BUG_ON(!guc->execbuf_client);
-       GEM_BUG_ON(!guc->preempt_client);
 
        seq_printf(m, "Doorbell map:\n");
        seq_printf(m, "\t%*pb\n", GUC_NUM_DOORBELLS, guc->doorbell_bitmap);
@@ -2346,8 +2339,11 @@ static int i915_guc_info(struct seq_file *m, void *data)
 
        seq_printf(m, "\nGuC execbuf client @ %p:\n", guc->execbuf_client);
        i915_guc_client_info(m, dev_priv, guc->execbuf_client);
-       seq_printf(m, "\nGuC preempt client @ %p:\n", guc->preempt_client);
-       i915_guc_client_info(m, dev_priv, guc->preempt_client);
+       if (guc->preempt_client) {
+               seq_printf(m, "\nGuC preempt client @ %p:\n",
+                          guc->preempt_client);
+               i915_guc_client_info(m, dev_priv, guc->preempt_client);
+       }
 
        i915_guc_log_info(m, dev_priv);
 
@@ -4083,10 +4079,8 @@ i915_drop_caches_set(void *data, u64 val)
        if (val & DROP_IDLE)
                drain_delayed_work(&dev_priv->gt.idle_work);
 
-       if (val & DROP_FREED) {
-               synchronize_rcu();
+       if (val & DROP_FREED)
                i915_gem_drain_freed_objects(dev_priv);
-       }
 
        return ret;
 }
index e9f1daf258fec84ff0036a777d99c3f408211e45..d09f8e661fbd7fd2005ac64559040de8a0b33368 100644 (file)
@@ -122,10 +122,90 @@ static bool i915_error_injected(struct drm_i915_private *dev_priv)
                      i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \
                      fmt, ##__VA_ARGS__)
 
+/* Map PCH device id to PCH type, or PCH_NONE if unknown. */
+static enum intel_pch
+intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
+{
+       switch (id) {
+       case INTEL_PCH_IBX_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
+               WARN_ON(!IS_GEN5(dev_priv));
+               return PCH_IBX;
+       case INTEL_PCH_CPT_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found CougarPoint PCH\n");
+               WARN_ON(!IS_GEN6(dev_priv) && !IS_IVYBRIDGE(dev_priv));
+               return PCH_CPT;
+       case INTEL_PCH_PPT_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found PantherPoint PCH\n");
+               WARN_ON(!IS_GEN6(dev_priv) && !IS_IVYBRIDGE(dev_priv));
+               /* PantherPoint is CPT compatible */
+               return PCH_CPT;
+       case INTEL_PCH_LPT_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found LynxPoint PCH\n");
+               WARN_ON(!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
+               WARN_ON(IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv));
+               return PCH_LPT;
+       case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
+               WARN_ON(!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
+               WARN_ON(!IS_HSW_ULT(dev_priv) && !IS_BDW_ULT(dev_priv));
+               return PCH_LPT;
+       case INTEL_PCH_WPT_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found WildcatPoint PCH\n");
+               WARN_ON(!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
+               WARN_ON(IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv));
+               /* WildcatPoint is LPT compatible */
+               return PCH_LPT;
+       case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found WildcatPoint LP PCH\n");
+               WARN_ON(!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv));
+               WARN_ON(!IS_HSW_ULT(dev_priv) && !IS_BDW_ULT(dev_priv));
+               /* WildcatPoint is LPT compatible */
+               return PCH_LPT;
+       case INTEL_PCH_SPT_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
+               WARN_ON(!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv));
+               return PCH_SPT;
+       case INTEL_PCH_SPT_LP_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
+               WARN_ON(!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv));
+               return PCH_SPT;
+       case INTEL_PCH_KBP_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found Kaby Lake PCH (KBP)\n");
+               WARN_ON(!IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv) &&
+                       !IS_COFFEELAKE(dev_priv));
+               return PCH_KBP;
+       case INTEL_PCH_CNP_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found Cannon Lake PCH (CNP)\n");
+               WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_COFFEELAKE(dev_priv));
+               return PCH_CNP;
+       case INTEL_PCH_CNP_LP_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found Cannon Lake LP PCH (CNP-LP)\n");
+               WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_COFFEELAKE(dev_priv));
+               return PCH_CNP;
+       case INTEL_PCH_ICP_DEVICE_ID_TYPE:
+               DRM_DEBUG_KMS("Found Ice Lake PCH\n");
+               WARN_ON(!IS_ICELAKE(dev_priv));
+               return PCH_ICP;
+       default:
+               return PCH_NONE;
+       }
+}
 
-static enum intel_pch intel_virt_detect_pch(struct drm_i915_private *dev_priv)
+static bool intel_is_virt_pch(unsigned short id,
+                             unsigned short svendor, unsigned short sdevice)
 {
-       enum intel_pch ret = PCH_NOP;
+       return (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
+               id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
+               (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
+                svendor == PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
+                sdevice == PCI_SUBDEVICE_ID_QEMU));
+}
+
+static unsigned short
+intel_virt_detect_pch(const struct drm_i915_private *dev_priv)
+{
+       unsigned short id = 0;
 
        /*
         * In a virtualized passthrough environment we can be in a
@@ -134,28 +214,25 @@ static enum intel_pch intel_virt_detect_pch(struct drm_i915_private *dev_priv)
         * make an educated guess as to which PCH is really there.
         */
 
-       if (IS_GEN5(dev_priv)) {
-               ret = PCH_IBX;
-               DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n");
-       } else if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
-               ret = PCH_CPT;
-               DRM_DEBUG_KMS("Assuming CougarPoint PCH\n");
-       } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
-               ret = PCH_LPT;
-               if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
-                       dev_priv->pch_id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
-               else
-                       dev_priv->pch_id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
-               DRM_DEBUG_KMS("Assuming LynxPoint PCH\n");
-       } else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
-               ret = PCH_SPT;
-               DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n");
-       } else if (IS_COFFEELAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
-               ret = PCH_CNP;
-               DRM_DEBUG_KMS("Assuming CannonPoint PCH\n");
-       }
+       if (IS_GEN5(dev_priv))
+               id = INTEL_PCH_IBX_DEVICE_ID_TYPE;
+       else if (IS_GEN6(dev_priv) || IS_IVYBRIDGE(dev_priv))
+               id = INTEL_PCH_CPT_DEVICE_ID_TYPE;
+       else if (IS_HSW_ULT(dev_priv) || IS_BDW_ULT(dev_priv))
+               id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE;
+       else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
+               id = INTEL_PCH_LPT_DEVICE_ID_TYPE;
+       else if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
+               id = INTEL_PCH_SPT_DEVICE_ID_TYPE;
+       else if (IS_COFFEELAKE(dev_priv) || IS_CANNONLAKE(dev_priv))
+               id = INTEL_PCH_CNP_DEVICE_ID_TYPE;
+
+       if (id)
+               DRM_DEBUG_KMS("Assuming PCH ID %04x\n", id);
+       else
+               DRM_DEBUG_KMS("Assuming no PCH\n");
 
-       return ret;
+       return id;
 }
 
 static void intel_detect_pch(struct drm_i915_private *dev_priv)
@@ -183,102 +260,32 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
         */
        while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) {
                unsigned short id;
+               enum intel_pch pch_type;
 
                if (pch->vendor != PCI_VENDOR_ID_INTEL)
                        continue;
 
                id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
 
-               dev_priv->pch_id = id;
-
-               if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_IBX;
-                       DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
-                       WARN_ON(!IS_GEN5(dev_priv));
-               } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_CPT;
-                       DRM_DEBUG_KMS("Found CougarPoint PCH\n");
-                       WARN_ON(!IS_GEN6(dev_priv) &&
-                               !IS_IVYBRIDGE(dev_priv));
-               } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
-                       /* PantherPoint is CPT compatible */
-                       dev_priv->pch_type = PCH_CPT;
-                       DRM_DEBUG_KMS("Found PantherPoint PCH\n");
-                       WARN_ON(!IS_GEN6(dev_priv) &&
-                               !IS_IVYBRIDGE(dev_priv));
-               } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_LPT;
-                       DRM_DEBUG_KMS("Found LynxPoint PCH\n");
-                       WARN_ON(!IS_HASWELL(dev_priv) &&
-                               !IS_BROADWELL(dev_priv));
-                       WARN_ON(IS_HSW_ULT(dev_priv) ||
-                               IS_BDW_ULT(dev_priv));
-               } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_LPT;
-                       DRM_DEBUG_KMS("Found LynxPoint LP PCH\n");
-                       WARN_ON(!IS_HASWELL(dev_priv) &&
-                               !IS_BROADWELL(dev_priv));
-                       WARN_ON(!IS_HSW_ULT(dev_priv) &&
-                               !IS_BDW_ULT(dev_priv));
-               } else if (id == INTEL_PCH_WPT_DEVICE_ID_TYPE) {
-                       /* WildcatPoint is LPT compatible */
-                       dev_priv->pch_type = PCH_LPT;
-                       DRM_DEBUG_KMS("Found WildcatPoint PCH\n");
-                       WARN_ON(!IS_HASWELL(dev_priv) &&
-                               !IS_BROADWELL(dev_priv));
-                       WARN_ON(IS_HSW_ULT(dev_priv) ||
-                               IS_BDW_ULT(dev_priv));
-               } else if (id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE) {
-                       /* WildcatPoint is LPT compatible */
-                       dev_priv->pch_type = PCH_LPT;
-                       DRM_DEBUG_KMS("Found WildcatPoint LP PCH\n");
-                       WARN_ON(!IS_HASWELL(dev_priv) &&
-                               !IS_BROADWELL(dev_priv));
-                       WARN_ON(!IS_HSW_ULT(dev_priv) &&
-                               !IS_BDW_ULT(dev_priv));
-               } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_SPT;
-                       DRM_DEBUG_KMS("Found SunrisePoint PCH\n");
-                       WARN_ON(!IS_SKYLAKE(dev_priv) &&
-                               !IS_KABYLAKE(dev_priv));
-               } else if (id == INTEL_PCH_SPT_LP_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_SPT;
-                       DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
-                       WARN_ON(!IS_SKYLAKE(dev_priv) &&
-                               !IS_KABYLAKE(dev_priv));
-               } else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_KBP;
-                       DRM_DEBUG_KMS("Found Kaby Lake PCH (KBP)\n");
-                       WARN_ON(!IS_SKYLAKE(dev_priv) &&
-                               !IS_KABYLAKE(dev_priv) &&
-                               !IS_COFFEELAKE(dev_priv));
-               } else if (id == INTEL_PCH_CNP_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_CNP;
-                       DRM_DEBUG_KMS("Found Cannon Lake PCH (CNP)\n");
-                       WARN_ON(!IS_CANNONLAKE(dev_priv) &&
-                               !IS_COFFEELAKE(dev_priv));
-               } else if (id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_CNP;
-                       DRM_DEBUG_KMS("Found Cannon Lake LP PCH (CNP-LP)\n");
-                       WARN_ON(!IS_CANNONLAKE(dev_priv) &&
-                               !IS_COFFEELAKE(dev_priv));
-               } else if (id == INTEL_PCH_ICP_DEVICE_ID_TYPE) {
-                       dev_priv->pch_type = PCH_ICP;
-                       DRM_DEBUG_KMS("Found Ice Lake PCH\n");
-                       WARN_ON(!IS_ICELAKE(dev_priv));
-               } else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE ||
-                          id == INTEL_PCH_P3X_DEVICE_ID_TYPE ||
-                          (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE &&
-                           pch->subsystem_vendor ==
-                           PCI_SUBVENDOR_ID_REDHAT_QUMRANET &&
-                           pch->subsystem_device ==
-                           PCI_SUBDEVICE_ID_QEMU)) {
-                       dev_priv->pch_type = intel_virt_detect_pch(dev_priv);
-               } else {
-                       continue;
+               pch_type = intel_pch_type(dev_priv, id);
+               if (pch_type != PCH_NONE) {
+                       dev_priv->pch_type = pch_type;
+                       dev_priv->pch_id = id;
+                       break;
+               } else if (intel_is_virt_pch(id, pch->subsystem_vendor,
+                                        pch->subsystem_device)) {
+                       id = intel_virt_detect_pch(dev_priv);
+                       if (id) {
+                               pch_type = intel_pch_type(dev_priv, id);
+                               if (WARN_ON(pch_type == PCH_NONE))
+                                       pch_type = PCH_NOP;
+                       } else {
+                               pch_type = PCH_NOP;
+                       }
+                       dev_priv->pch_type = pch_type;
+                       dev_priv->pch_id = id;
+                       break;
                }
-
-               break;
        }
        if (!pch)
                DRM_DEBUG_KMS("No PCH found.\n");
@@ -286,8 +293,8 @@ static void intel_detect_pch(struct drm_i915_private *dev_priv)
        pci_dev_put(pch);
 }
 
-static int i915_getparam(struct drm_device *dev, void *data,
-                        struct drm_file *file_priv)
+static int i915_getparam_ioctl(struct drm_device *dev, void *data,
+                              struct drm_file *file_priv)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct pci_dev *pdev = dev_priv->drm.pdev;
@@ -381,13 +388,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
                value = i915_gem_mmap_gtt_version();
                break;
        case I915_PARAM_HAS_SCHEDULER:
-               value = 0;
-               if (dev_priv->engine[RCS] && dev_priv->engine[RCS]->schedule) {
-                       value |= I915_SCHEDULER_CAP_ENABLED;
-                       value |= I915_SCHEDULER_CAP_PRIORITY;
-                       if (HAS_LOGICAL_RING_PREEMPTION(dev_priv))
-                               value |= I915_SCHEDULER_CAP_PREEMPTION;
-               }
+               value = dev_priv->caps.scheduler;
                break;
 
        case I915_PARAM_MMAP_VERSION:
@@ -879,6 +880,7 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv)
 /**
  * i915_driver_init_early - setup state not requiring device access
  * @dev_priv: device private
+ * @ent: the matching pci_device_id
  *
  * Initialize everything that is a "SW-only" state, that is state not
  * requiring accessing the device or exposing the driver via kernel internal
@@ -904,11 +906,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
 
        BUILD_BUG_ON(INTEL_MAX_PLATFORMS >
                     sizeof(device_info->platform_mask) * BITS_PER_BYTE);
-       device_info->platform_mask = BIT(device_info->platform);
-
        BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE);
-       device_info->gen_mask = BIT(device_info->gen - 1);
-
        spin_lock_init(&dev_priv->irq_lock);
        spin_lock_init(&dev_priv->gpu_error.lock);
        mutex_init(&dev_priv->backlight_lock);
@@ -1446,19 +1444,7 @@ void i915_driver_unload(struct drm_device *dev)
 
        intel_modeset_cleanup(dev);
 
-       /*
-        * free the memory space allocated for the child device
-        * config parsed from VBT
-        */
-       if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) {
-               kfree(dev_priv->vbt.child_dev);
-               dev_priv->vbt.child_dev = NULL;
-               dev_priv->vbt.child_dev_num = 0;
-       }
-       kfree(dev_priv->vbt.sdvo_lvds_vbt_mode);
-       dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
-       kfree(dev_priv->vbt.lfp_lvds_vbt_mode);
-       dev_priv->vbt.lfp_lvds_vbt_mode = NULL;
+       intel_bios_cleanup(dev_priv);
 
        vga_switcheroo_unregister_client(pdev);
        vga_client_register(pdev, NULL, NULL, NULL);
@@ -1925,7 +1911,6 @@ void i915_reset(struct drm_i915_private *i915, unsigned int flags)
        ret = i915_gem_reset_prepare(i915);
        if (ret) {
                dev_err(i915->drm.dev, "GPU recovery failed\n");
-               intel_gpu_reset(i915, ALL_ENGINES);
                goto taint;
        }
 
@@ -1957,7 +1942,8 @@ void i915_reset(struct drm_i915_private *i915, unsigned int flags)
         */
        ret = i915_ggtt_enable_hw(i915);
        if (ret) {
-               DRM_ERROR("Failed to re-enable GGTT following reset %d\n", ret);
+               DRM_ERROR("Failed to re-enable GGTT following reset (%d)\n",
+                         ret);
                goto error;
        }
 
@@ -1974,7 +1960,8 @@ void i915_reset(struct drm_i915_private *i915, unsigned int flags)
         */
        ret = i915_gem_init_hw(i915);
        if (ret) {
-               DRM_ERROR("Failed hw init on reset %d\n", ret);
+               DRM_ERROR("Failed to initialise HW following reset (%d)\n",
+                         ret);
                goto error;
        }
 
@@ -2006,6 +1993,7 @@ taint:
 error:
        i915_gem_set_wedged(i915);
        i915_gem_retire_requests(i915);
+       intel_gpu_reset(i915, ALL_ENGINES);
        goto finish;
 }
 
@@ -2795,7 +2783,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, drm_noop, DRM_AUTH),
        DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, drm_noop, DRM_AUTH),
        DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, drm_noop, DRM_AUTH),
-       DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH|DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_SETPARAM, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH),
        DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH),
@@ -2807,8 +2795,8 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, drm_noop, DRM_AUTH),
        DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF_DRV(I915_GEM_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-       DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
-       DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2_WR, i915_gem_execbuffer2, DRM_AUTH|DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2_WR, i915_gem_execbuffer2_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_reject_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
        DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
@@ -2827,11 +2815,11 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
        DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_RENDER_ALLOW),
-       DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0),
+       DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id_ioctl, 0),
        DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
-       DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey, DRM_MASTER|DRM_CONTROL_ALLOW),
+       DRM_IOCTL_DEF_DRV(I915_SET_SPRITE_COLORKEY, intel_sprite_set_colorkey_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GET_SPRITE_COLORKEY, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
        DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
index ad1fc845cd1b2bbf076f38101c2c19c109e09420..92883a40bdd51f6f587a0f51851826f3896245a3 100644 (file)
@@ -83,8 +83,8 @@
 
 #define DRIVER_NAME            "i915"
 #define DRIVER_DESC            "Intel Graphics"
-#define DRIVER_DATE            "20180207"
-#define DRIVER_TIMESTAMP       1517988364
+#define DRIVER_DATE            "20180221"
+#define DRIVER_TIMESTAMP       1519219289
 
 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and
  * WARN_ON()) for hw state sanity checks to check for unexpected conditions
@@ -472,6 +472,7 @@ struct i915_gpu_state {
        u32 reset_count;
        u32 suspend_count;
        struct intel_device_info device_info;
+       struct intel_driver_caps driver_caps;
        struct i915_params params;
 
        struct i915_error_uc {
@@ -666,6 +667,7 @@ struct intel_fbc {
         */
        struct intel_fbc_state_cache {
                struct i915_vma *vma;
+               unsigned long flags;
 
                struct {
                        unsigned int mode_flags;
@@ -704,6 +706,7 @@ struct intel_fbc {
         */
        struct intel_fbc_reg_params {
                struct i915_vma *vma;
+               unsigned long flags;
 
                struct {
                        enum pipe pipe;
@@ -722,7 +725,7 @@ struct intel_fbc {
 
        struct intel_fbc_work {
                bool scheduled;
-               u32 scheduled_vblank;
+               u64 scheduled_vblank;
                struct work_struct work;
        } work;
 
@@ -946,6 +949,8 @@ struct intel_rps {
 
 struct intel_rc6 {
        bool enabled;
+       u64 prev_hw_residency[4];
+       u64 cur_residency[4];
 };
 
 struct intel_llc_pstate {
@@ -1092,6 +1097,11 @@ struct i915_gem_mm {
        struct llist_head free_list;
        struct work_struct free_work;
        spinlock_t free_lock;
+       /**
+        * Count of objects pending destructions. Used to skip needlessly
+        * waiting on an RCU barrier if no objects are waiting to be freed.
+        */
+       atomic_t free_count;
 
        /**
         * Small stash of WC pages
@@ -1356,6 +1366,7 @@ struct intel_vbt_data {
                u32 size;
                u8 *data;
                const u8 *sequence[MIPI_SEQ_MAX];
+               u8 *deassert_seq; /* Used by fixup_mipi_sequences() */
        } dsi;
 
        int crt_ddc_pin;
@@ -1815,6 +1826,7 @@ struct drm_i915_private {
        struct kmem_cache *priorities;
 
        const struct intel_device_info info;
+       struct intel_driver_caps caps;
 
        /**
         * Data Stolen Memory - aka "i915 stolen memory" gives us the start and
@@ -2419,12 +2431,16 @@ enum hdmi_force_audio {
  * We have one bit per pipe and per scanout plane type.
  */
 #define INTEL_FRONTBUFFER_BITS_PER_PIPE 8
-#define INTEL_FRONTBUFFER(pipe, plane_id) \
-       (1 << ((plane_id) + INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
+#define INTEL_FRONTBUFFER(pipe, plane_id) ({ \
+       BUILD_BUG_ON(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES > 32); \
+       BUILD_BUG_ON(I915_MAX_PLANES > INTEL_FRONTBUFFER_BITS_PER_PIPE); \
+       BIT((plane_id) + INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)); \
+})
 #define INTEL_FRONTBUFFER_OVERLAY(pipe) \
-       (1 << (INTEL_FRONTBUFFER_BITS_PER_PIPE - 1 + INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
+       BIT(INTEL_FRONTBUFFER_BITS_PER_PIPE - 1 + INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))
 #define INTEL_FRONTBUFFER_ALL_MASK(pipe) \
-       (0xff << (INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)))
+       GENMASK(INTEL_FRONTBUFFER_BITS_PER_PIPE * ((pipe) + 1) - 1, \
+               INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe))
 
 /*
  * Optimised SGL iterator for GEM objects
@@ -2799,7 +2815,7 @@ intel_info(const struct drm_i915_private *dev_priv)
 
 #define HAS_FW_BLC(dev_priv)   (INTEL_GEN(dev_priv) > 2)
 #define HAS_FBC(dev_priv)      ((dev_priv)->info.has_fbc)
-#define HAS_CUR_FBC(dev_priv)  (!HAS_GMCH_DISPLAY(dev_priv) && INTEL_INFO(dev_priv)->gen >= 7)
+#define HAS_CUR_FBC(dev_priv)  (!HAS_GMCH_DISPLAY(dev_priv) && INTEL_GEN(dev_priv) >= 7)
 
 #define HAS_IPS(dev_priv)      (IS_HSW_ULT(dev_priv) || IS_BROADWELL(dev_priv))
 
@@ -2862,19 +2878,20 @@ intel_info(const struct drm_i915_private *dev_priv)
 #define INTEL_PCH_QEMU_DEVICE_ID_TYPE          0x2900 /* qemu q35 has 2918 */
 
 #define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type)
+#define INTEL_PCH_ID(dev_priv) ((dev_priv)->pch_id)
 #define HAS_PCH_ICP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ICP)
 #define HAS_PCH_CNP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CNP)
 #define HAS_PCH_CNP_LP(dev_priv) \
-       ((dev_priv)->pch_id == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE)
+       (INTEL_PCH_ID(dev_priv) == INTEL_PCH_CNP_LP_DEVICE_ID_TYPE)
 #define HAS_PCH_KBP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_KBP)
 #define HAS_PCH_SPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_SPT)
 #define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT)
 #define HAS_PCH_LPT_LP(dev_priv) \
-       ((dev_priv)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE || \
-        (dev_priv)->pch_id == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE)
+       (INTEL_PCH_ID(dev_priv) == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE || \
+        INTEL_PCH_ID(dev_priv) == INTEL_PCH_WPT_LP_DEVICE_ID_TYPE)
 #define HAS_PCH_LPT_H(dev_priv) \
-       ((dev_priv)->pch_id == INTEL_PCH_LPT_DEVICE_ID_TYPE || \
-        (dev_priv)->pch_id == INTEL_PCH_WPT_DEVICE_ID_TYPE)
+       (INTEL_PCH_ID(dev_priv) == INTEL_PCH_LPT_DEVICE_ID_TYPE || \
+        INTEL_PCH_ID(dev_priv) == INTEL_PCH_WPT_DEVICE_ID_TYPE)
 #define HAS_PCH_CPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CPT)
 #define HAS_PCH_IBX(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_IBX)
 #define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP)
@@ -3081,10 +3098,10 @@ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
                              struct drm_file *file_priv);
 int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
                             struct drm_file *file_priv);
-int i915_gem_execbuffer(struct drm_device *dev, void *data,
-                       struct drm_file *file_priv);
-int i915_gem_execbuffer2(struct drm_device *dev, void *data,
-                        struct drm_file *file_priv);
+int i915_gem_execbuffer_ioctl(struct drm_device *dev, void *data,
+                             struct drm_file *file_priv);
+int i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,
+                              struct drm_file *file_priv);
 int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
                        struct drm_file *file_priv);
 int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data,
@@ -3128,6 +3145,9 @@ void i915_gem_free_object(struct drm_gem_object *obj);
 
 static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915)
 {
+       if (!atomic_read(&i915->mm.free_count))
+               return;
+
        /* A single pass should suffice to release all the freed objects (along
         * most call paths) , but be a little more paranoid in that freeing
         * the objects does take a little amount of time, during which the rcu
@@ -3399,7 +3419,8 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write);
 struct i915_vma * __must_check
 i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
                                     u32 alignment,
-                                    const struct i915_ggtt_view *view);
+                                    const struct i915_ggtt_view *view,
+                                    unsigned int flags);
 void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
 int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
                                int align);
@@ -3675,6 +3696,7 @@ extern void intel_i2c_reset(struct drm_i915_private *dev_priv);
 
 /* intel_bios.c */
 void intel_bios_init(struct drm_i915_private *dev_priv);
+void intel_bios_cleanup(struct drm_i915_private *dev_priv);
 bool intel_bios_is_valid_vbt(const void *buf, size_t size);
 bool intel_bios_is_tv_present(struct drm_i915_private *dev_priv);
 bool intel_bios_is_lvds_present(struct drm_i915_private *dev_priv, u8 *i2c_pin);
index 1632f18e6a64deca50b228ada59b017b98d1dde1..43afa1c1b14f5784c4fd53ea4c66307be800faa6 100644 (file)
@@ -240,8 +240,8 @@ err_phys:
 
 static void __start_cpu_write(struct drm_i915_gem_object *obj)
 {
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU;
-       obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+       obj->read_domains = I915_GEM_DOMAIN_CPU;
+       obj->write_domain = I915_GEM_DOMAIN_CPU;
        if (cpu_write_needs_clflush(obj))
                obj->cache_dirty = true;
 }
@@ -257,7 +257,7 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
                obj->mm.dirty = false;
 
        if (needs_clflush &&
-           (obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0 &&
+           (obj->read_domains & I915_GEM_DOMAIN_CPU) == 0 &&
            !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ))
                drm_clflush_sg(pages);
 
@@ -703,10 +703,10 @@ flush_write_domain(struct drm_i915_gem_object *obj, unsigned int flush_domains)
        struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
        struct i915_vma *vma;
 
-       if (!(obj->base.write_domain & flush_domains))
+       if (!(obj->write_domain & flush_domains))
                return;
 
-       switch (obj->base.write_domain) {
+       switch (obj->write_domain) {
        case I915_GEM_DOMAIN_GTT:
                i915_gem_flush_ggtt_writes(dev_priv);
 
@@ -731,7 +731,7 @@ flush_write_domain(struct drm_i915_gem_object *obj, unsigned int flush_domains)
                break;
        }
 
-       obj->base.write_domain = 0;
+       obj->write_domain = 0;
 }
 
 static inline int
@@ -831,7 +831,7 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj,
         * anyway again before the next pread happens.
         */
        if (!obj->cache_dirty &&
-           !(obj->base.read_domains & I915_GEM_DOMAIN_CPU))
+           !(obj->read_domains & I915_GEM_DOMAIN_CPU))
                *needs_clflush = CLFLUSH_BEFORE;
 
 out:
@@ -890,7 +890,7 @@ int i915_gem_obj_prepare_shmem_write(struct drm_i915_gem_object *obj,
                 * Same trick applies to invalidate partially written
                 * cachelines read before writing.
                 */
-               if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU))
+               if (!(obj->read_domains & I915_GEM_DOMAIN_CPU))
                        *needs_clflush |= CLFLUSH_BEFORE;
        }
 
@@ -2391,8 +2391,8 @@ static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
         * wasn't in the GTT, there shouldn't be any way it could have been in
         * a GPU cache
         */
-       GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
-       GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
+       GEM_BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS);
+       GEM_BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS);
 
        st = kmalloc(sizeof(*st), GFP_KERNEL);
        if (st == NULL)
@@ -3205,6 +3205,9 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
                        intel_engine_dump(engine, &p, "%s\n", engine->name);
        }
 
+       set_bit(I915_WEDGED, &i915->gpu_error.flags);
+       smp_mb__after_atomic();
+
        /*
         * First, stop submission to hw, but do not yet complete requests by
         * rolling the global seqno forward (since this would complete requests
@@ -3229,8 +3232,11 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
                 * start to complete all requests.
                 */
                engine->submit_request = nop_complete_submit_request;
+               engine->schedule = NULL;
        }
 
+       i915->caps.scheduler = 0;
+
        /*
         * Make sure no request can slip through without getting completed by
         * either this call here to intel_engine_init_global_seqno, or the one
@@ -3241,7 +3247,8 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
        for_each_engine(engine, i915, id) {
                unsigned long flags;
 
-               /* Mark all pending requests as complete so that any concurrent
+               /*
+                * Mark all pending requests as complete so that any concurrent
                 * (lockless) lookup doesn't try and wait upon the request as we
                 * reset it.
                 */
@@ -3251,7 +3258,6 @@ void i915_gem_set_wedged(struct drm_i915_private *i915)
                spin_unlock_irqrestore(&engine->timeline->lock, flags);
        }
 
-       set_bit(I915_WEDGED, &i915->gpu_error.flags);
        wake_up_all(&i915->gpu_error.reset_queue);
 }
 
@@ -3697,7 +3703,7 @@ static void __i915_gem_object_flush_for_display(struct drm_i915_gem_object *obj)
        flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
        if (obj->cache_dirty)
                i915_gem_clflush_object(obj, I915_CLFLUSH_FORCE);
-       obj->base.write_domain = 0;
+       obj->write_domain = 0;
 }
 
 void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj)
@@ -3734,7 +3740,7 @@ i915_gem_object_set_to_wc_domain(struct drm_i915_gem_object *obj, bool write)
        if (ret)
                return ret;
 
-       if (obj->base.write_domain == I915_GEM_DOMAIN_WC)
+       if (obj->write_domain == I915_GEM_DOMAIN_WC)
                return 0;
 
        /* Flush and acquire obj->pages so that we are coherent through
@@ -3755,17 +3761,17 @@ i915_gem_object_set_to_wc_domain(struct drm_i915_gem_object *obj, bool write)
         * coherent writes from the GPU, by effectively invalidating the
         * WC domain upon first access.
         */
-       if ((obj->base.read_domains & I915_GEM_DOMAIN_WC) == 0)
+       if ((obj->read_domains & I915_GEM_DOMAIN_WC) == 0)
                mb();
 
        /* It should now be out of any other write domains, and we can update
         * the domain values for our changes.
         */
-       GEM_BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_WC) != 0);
-       obj->base.read_domains |= I915_GEM_DOMAIN_WC;
+       GEM_BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_WC) != 0);
+       obj->read_domains |= I915_GEM_DOMAIN_WC;
        if (write) {
-               obj->base.read_domains = I915_GEM_DOMAIN_WC;
-               obj->base.write_domain = I915_GEM_DOMAIN_WC;
+               obj->read_domains = I915_GEM_DOMAIN_WC;
+               obj->write_domain = I915_GEM_DOMAIN_WC;
                obj->mm.dirty = true;
        }
 
@@ -3797,7 +3803,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
        if (ret)
                return ret;
 
-       if (obj->base.write_domain == I915_GEM_DOMAIN_GTT)
+       if (obj->write_domain == I915_GEM_DOMAIN_GTT)
                return 0;
 
        /* Flush and acquire obj->pages so that we are coherent through
@@ -3818,17 +3824,17 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write)
         * coherent writes from the GPU, by effectively invalidating the
         * GTT domain upon first access.
         */
-       if ((obj->base.read_domains & I915_GEM_DOMAIN_GTT) == 0)
+       if ((obj->read_domains & I915_GEM_DOMAIN_GTT) == 0)
                mb();
 
        /* It should now be out of any other write domains, and we can update
         * the domain values for our changes.
         */
-       GEM_BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
-       obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
+       GEM_BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0);
+       obj->read_domains |= I915_GEM_DOMAIN_GTT;
        if (write) {
-               obj->base.read_domains = I915_GEM_DOMAIN_GTT;
-               obj->base.write_domain = I915_GEM_DOMAIN_GTT;
+               obj->read_domains = I915_GEM_DOMAIN_GTT;
+               obj->write_domain = I915_GEM_DOMAIN_GTT;
                obj->mm.dirty = true;
        }
 
@@ -4072,7 +4078,8 @@ out:
 struct i915_vma *
 i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
                                     u32 alignment,
-                                    const struct i915_ggtt_view *view)
+                                    const struct i915_ggtt_view *view,
+                                    unsigned int flags)
 {
        struct i915_vma *vma;
        int ret;
@@ -4109,25 +4116,14 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
         * try to preserve the existing ABI).
         */
        vma = ERR_PTR(-ENOSPC);
-       if (!view || view->type == I915_GGTT_VIEW_NORMAL)
+       if ((flags & PIN_MAPPABLE) == 0 &&
+           (!view || view->type == I915_GGTT_VIEW_NORMAL))
                vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment,
-                                              PIN_MAPPABLE | PIN_NONBLOCK);
-       if (IS_ERR(vma)) {
-               struct drm_i915_private *i915 = to_i915(obj->base.dev);
-               unsigned int flags;
-
-               /* Valleyview is definitely limited to scanning out the first
-                * 512MiB. Lets presume this behaviour was inherited from the
-                * g4x display engine and that all earlier gen are similarly
-                * limited. Testing suggests that it is a little more
-                * complicated than this. For example, Cherryview appears quite
-                * happy to scanout from anywhere within its global aperture.
-                */
-               flags = 0;
-               if (HAS_GMCH_DISPLAY(i915))
-                       flags = PIN_MAPPABLE;
+                                              flags |
+                                              PIN_MAPPABLE |
+                                              PIN_NONBLOCK);
+       if (IS_ERR(vma))
                vma = i915_gem_object_ggtt_pin(obj, view, 0, alignment, flags);
-       }
        if (IS_ERR(vma))
                goto err_unpin_global;
 
@@ -4140,7 +4136,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
        /* It should now be out of any other write domains, and we can update
         * the domain values for our changes.
         */
-       obj->base.read_domains |= I915_GEM_DOMAIN_GTT;
+       obj->read_domains |= I915_GEM_DOMAIN_GTT;
 
        return vma;
 
@@ -4193,15 +4189,15 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
        flush_write_domain(obj, ~I915_GEM_DOMAIN_CPU);
 
        /* Flush the CPU cache if it's still invalid. */
-       if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) {
+       if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) {
                i915_gem_clflush_object(obj, I915_CLFLUSH_SYNC);
-               obj->base.read_domains |= I915_GEM_DOMAIN_CPU;
+               obj->read_domains |= I915_GEM_DOMAIN_CPU;
        }
 
        /* It should now be out of any other write domains, and we can update
         * the domain values for our changes.
         */
-       GEM_BUG_ON(obj->base.write_domain & ~I915_GEM_DOMAIN_CPU);
+       GEM_BUG_ON(obj->write_domain & ~I915_GEM_DOMAIN_CPU);
 
        /* If we're writing through the CPU, then the GPU read domains will
         * need to be invalidated at next use.
@@ -4276,7 +4272,8 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
 
        lockdep_assert_held(&obj->base.dev->struct_mutex);
 
-       if (!view && flags & PIN_MAPPABLE) {
+       if (flags & PIN_MAPPABLE &&
+           (!view || view->type == I915_GGTT_VIEW_NORMAL)) {
                /* If the required space is larger than the available
                 * aperture, we will not able to find a slot for the
                 * object and unbinding the object now will be in
@@ -4637,8 +4634,8 @@ i915_gem_object_create(struct drm_i915_private *dev_priv, u64 size)
 
        i915_gem_object_init(obj, &i915_gem_object_ops);
 
-       obj->base.write_domain = I915_GEM_DOMAIN_CPU;
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+       obj->write_domain = I915_GEM_DOMAIN_CPU;
+       obj->read_domains = I915_GEM_DOMAIN_CPU;
 
        if (HAS_LLC(dev_priv))
                /* On some devices, we can have the GPU use the LLC (the CPU
@@ -4752,6 +4749,9 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
                kfree(obj->bit_17);
                i915_gem_object_free(obj);
 
+               GEM_BUG_ON(!atomic_read(&i915->mm.free_count));
+               atomic_dec(&i915->mm.free_count);
+
                if (on)
                        cond_resched();
        }
@@ -4840,6 +4840,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
         * i915_gem_busy_ioctl(). For the corresponding synchronized
         * lookup see i915_gem_object_lookup_rcu().
         */
+       atomic_inc(&to_i915(obj->base.dev)->mm.free_count);
        call_rcu(&obj->rcu, __i915_gem_free_object_rcu);
 }
 
@@ -4882,10 +4883,8 @@ void i915_gem_sanitize(struct drm_i915_private *i915)
         * it may impact the display and we are uncertain about the stability
         * of the reset, so this could be applied to even earlier gen.
         */
-       if (INTEL_GEN(i915) >= 5) {
-               int reset = intel_gpu_reset(i915, ALL_ENGINES);
-               WARN_ON(reset && reset != -ENODEV);
-       }
+       if (INTEL_GEN(i915) >= 5 && intel_has_gpu_reset(i915))
+               WARN_ON(intel_gpu_reset(i915, ALL_ENGINES));
 }
 
 int i915_gem_suspend(struct drm_i915_private *dev_priv)
@@ -5065,8 +5064,11 @@ static int __i915_gem_restart_engines(void *data)
 
        for_each_engine(engine, i915, id) {
                err = engine->init_hw(engine);
-               if (err)
+               if (err) {
+                       DRM_ERROR("Failed to restart %s (%d)\n",
+                                 engine->name, err);
                        return err;
+               }
        }
 
        return 0;
@@ -5118,14 +5120,16 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv)
 
        ret = i915_ppgtt_init_hw(dev_priv);
        if (ret) {
-               DRM_ERROR("PPGTT enable HW failed %d\n", ret);
+               DRM_ERROR("Enabling PPGTT failed (%d)\n", ret);
                goto out;
        }
 
        /* We can't enable contexts until all firmware is loaded */
        ret = intel_uc_init_hw(dev_priv);
-       if (ret)
+       if (ret) {
+               DRM_ERROR("Enabling uc failed (%d)\n", ret);
                goto out;
+       }
 
        intel_mocs_init_l3cc_table(dev_priv);
 
@@ -5415,10 +5419,10 @@ i915_gem_load_init_fences(struct drm_i915_private *dev_priv)
 {
        int i;
 
-       if (INTEL_INFO(dev_priv)->gen >= 7 && !IS_VALLEYVIEW(dev_priv) &&
+       if (INTEL_GEN(dev_priv) >= 7 && !IS_VALLEYVIEW(dev_priv) &&
            !IS_CHERRYVIEW(dev_priv))
                dev_priv->num_fence_regs = 32;
-       else if (INTEL_INFO(dev_priv)->gen >= 4 ||
+       else if (INTEL_GEN(dev_priv) >= 4 ||
                 IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
                 IS_G33(dev_priv) || IS_PINEVIEW(dev_priv))
                dev_priv->num_fence_regs = 16;
@@ -5537,7 +5541,8 @@ err_out:
 void i915_gem_load_cleanup(struct drm_i915_private *dev_priv)
 {
        i915_gem_drain_freed_objects(dev_priv);
-       WARN_ON(!llist_empty(&dev_priv->mm.free_list));
+       GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list));
+       GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count));
        WARN_ON(dev_priv->mm.object_count);
 
        mutex_lock(&dev_priv->drm.struct_mutex);
@@ -5693,7 +5698,7 @@ i915_gem_object_create_from_data(struct drm_i915_private *dev_priv,
        if (IS_ERR(obj))
                return obj;
 
-       GEM_BUG_ON(obj->base.write_domain != I915_GEM_DOMAIN_CPU);
+       GEM_BUG_ON(obj->write_domain != I915_GEM_DOMAIN_CPU);
 
        file = obj->base.filp;
        offset = 0;
index b9b53ac141766bd941d5fcb677801f5ce14e37db..f5c570d35b2a2dd75fbcad4f4205e84e1e58f811 100644 (file)
@@ -177,7 +177,7 @@ bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
        } else if (obj->mm.pages) {
                __i915_do_clflush(obj);
        } else {
-               GEM_BUG_ON(obj->base.write_domain != I915_GEM_DOMAIN_CPU);
+               GEM_BUG_ON(obj->write_domain != I915_GEM_DOMAIN_CPU);
        }
 
        obj->cache_dirty = false;
index 648e7536ff51e0eae1365971293ab150f72d9956..3d75f484f6e5abb2cf83efedccfd005fd954e95e 100644 (file)
@@ -338,11 +338,6 @@ static void __destroy_hw_context(struct i915_gem_context *ctx,
        context_close(ctx);
 }
 
-/**
- * The default context needs to exist per ring that uses contexts. It stores the
- * context state of the GPU for applications that don't utilize HW contexts, as
- * well as an idle case.
- */
 static struct i915_gem_context *
 i915_gem_create_context(struct drm_i915_private *dev_priv,
                        struct drm_i915_file_private *file_priv)
@@ -449,12 +444,18 @@ destroy_kernel_context(struct i915_gem_context **ctxp)
        i915_gem_context_free(ctx);
 }
 
+static bool needs_preempt_context(struct drm_i915_private *i915)
+{
+       return HAS_LOGICAL_RING_PREEMPTION(i915);
+}
+
 int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
 {
        struct i915_gem_context *ctx;
-       int err;
 
+       /* Reassure ourselves we are only called once */
        GEM_BUG_ON(dev_priv->kernel_context);
+       GEM_BUG_ON(dev_priv->preempt_context);
 
        INIT_LIST_HEAD(&dev_priv->contexts.list);
        INIT_WORK(&dev_priv->contexts.free_work, contexts_free_worker);
@@ -468,8 +469,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
        ctx = i915_gem_context_create_kernel(dev_priv, I915_PRIORITY_MIN);
        if (IS_ERR(ctx)) {
                DRM_ERROR("Failed to create default global context\n");
-               err = PTR_ERR(ctx);
-               goto err;
+               return PTR_ERR(ctx);
        }
        /*
         * For easy recognisablity, we want the kernel context to be 0 and then
@@ -479,23 +479,18 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
        dev_priv->kernel_context = ctx;
 
        /* highest priority; preempting task */
-       ctx = i915_gem_context_create_kernel(dev_priv, INT_MAX);
-       if (IS_ERR(ctx)) {
-               DRM_ERROR("Failed to create default preempt context\n");
-               err = PTR_ERR(ctx);
-               goto err_kernel_context;
+       if (needs_preempt_context(dev_priv)) {
+               ctx = i915_gem_context_create_kernel(dev_priv, INT_MAX);
+               if (!IS_ERR(ctx))
+                       dev_priv->preempt_context = ctx;
+               else
+                       DRM_ERROR("Failed to create preempt context; disabling preemption\n");
        }
-       dev_priv->preempt_context = ctx;
 
        DRM_DEBUG_DRIVER("%s context support initialized\n",
                         dev_priv->engine[RCS]->context_size ? "logical" :
                         "fake");
        return 0;
-
-err_kernel_context:
-       destroy_kernel_context(&dev_priv->kernel_context);
-err:
-       return err;
 }
 
 void i915_gem_contexts_lost(struct drm_i915_private *dev_priv)
@@ -521,7 +516,8 @@ void i915_gem_contexts_fini(struct drm_i915_private *i915)
 {
        lockdep_assert_held(&i915->drm.struct_mutex);
 
-       destroy_kernel_context(&i915->preempt_context);
+       if (i915->preempt_context)
+               destroy_kernel_context(&i915->preempt_context);
        destroy_kernel_context(&i915->kernel_context);
 
        /* Must free all deferred contexts (via flush_workqueue) first */
@@ -803,11 +799,11 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
 
        case I915_CONTEXT_PARAM_PRIORITY:
                {
-                       int priority = args->value;
+                       s64 priority = args->value;
 
                        if (args->size)
                                ret = -EINVAL;
-                       else if (!to_i915(dev)->engine[RCS]->schedule)
+                       else if (!(to_i915(dev)->caps.scheduler & I915_SCHEDULER_CAP_PRIORITY))
                                ret = -ENODEV;
                        else if (priority > I915_CONTEXT_MAX_USER_PRIORITY ||
                                 priority < I915_CONTEXT_MIN_USER_PRIORITY)
index 4bfb72f8e1cb22d21fd3fb16bab7f25de40ef21d..a681c5b891ff247b623887e6f0ef98dda8861c46 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/list.h>
 #include <linux/radix-tree.h>
 
+#include "i915_gem.h"
+
 struct pid;
 
 struct drm_device;
@@ -36,6 +38,7 @@ struct drm_file;
 
 struct drm_i915_private;
 struct drm_i915_file_private;
+struct drm_i915_gem_request;
 struct i915_hw_ppgtt;
 struct i915_vma;
 struct intel_ring;
index 864439a214c83c32d663e49bf05c50cd96f3ffb3..69a7aec49e84e06d70b5800af653d951d522049a 100644 (file)
@@ -330,8 +330,8 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
         * write-combined buffer or a delay through the chipset for GTT
         * writes that do require us to treat GTT as a separate cache domain.)
         */
-       obj->base.read_domains = I915_GEM_DOMAIN_GTT;
-       obj->base.write_domain = 0;
+       obj->read_domains = I915_GEM_DOMAIN_GTT;
+       obj->write_domain = 0;
 
        return &obj->base;
 
index 4401068ff468ad36aef1d5df5277e2f008f01bb3..4eb28e84fda46e3127234f8a0862bf4d7ef92967 100644 (file)
@@ -505,6 +505,8 @@ eb_add_vma(struct i915_execbuffer *eb, unsigned int i, struct i915_vma *vma)
                list_add_tail(&vma->exec_link, &eb->unbound);
                if (drm_mm_node_allocated(&vma->node))
                        err = i915_vma_unbind(vma);
+               if (unlikely(err))
+                       vma->exec_flags = NULL;
        }
        return err;
 }
@@ -1073,7 +1075,7 @@ static int __reloc_gpu_alloc(struct i915_execbuffer *eb,
        u32 *cmd;
        int err;
 
-       GEM_BUG_ON(vma->obj->base.write_domain & I915_GEM_DOMAIN_CPU);
+       GEM_BUG_ON(vma->obj->write_domain & I915_GEM_DOMAIN_CPU);
 
        obj = i915_gem_batch_pool_get(&eb->engine->batch_pool, PAGE_SIZE);
        if (IS_ERR(obj))
@@ -1861,16 +1863,16 @@ void i915_vma_move_to_active(struct i915_vma *vma,
        i915_gem_active_set(&vma->last_read[idx], req);
        list_move_tail(&vma->vm_link, &vma->vm->active_list);
 
-       obj->base.write_domain = 0;
+       obj->write_domain = 0;
        if (flags & EXEC_OBJECT_WRITE) {
-               obj->base.write_domain = I915_GEM_DOMAIN_RENDER;
+               obj->write_domain = I915_GEM_DOMAIN_RENDER;
 
                if (intel_fb_obj_invalidate(obj, ORIGIN_CS))
                        i915_gem_active_set(&obj->frontbuffer_write, req);
 
-               obj->base.read_domains = 0;
+               obj->read_domains = 0;
        }
-       obj->base.read_domains |= I915_GEM_GPU_DOMAINS;
+       obj->read_domains |= I915_GEM_GPU_DOMAINS;
 
        if (flags & EXEC_OBJECT_NEEDS_FENCE)
                i915_gem_active_set(&vma->last_fence, req);
@@ -1973,7 +1975,7 @@ static int eb_submit(struct i915_execbuffer *eb)
        return 0;
 }
 
-/**
+/*
  * Find one BSD ring to dispatch the corresponding BSD command.
  * The engine index is returned.
  */
@@ -2410,7 +2412,7 @@ err_request:
        if (out_fence) {
                if (err == 0) {
                        fd_install(out_fence_fd, out_fence->file);
-                       args->rsvd2 &= GENMASK_ULL(0, 31); /* keep in-fence */
+                       args->rsvd2 &= GENMASK_ULL(31, 0); /* keep in-fence */
                        args->rsvd2 |= (u64)out_fence_fd << 32;
                        out_fence_fd = -1;
                } else {
@@ -2463,8 +2465,8 @@ static bool check_buffer_count(size_t count)
  * list array and passes it to the real function.
  */
 int
-i915_gem_execbuffer(struct drm_device *dev, void *data,
-                   struct drm_file *file)
+i915_gem_execbuffer_ioctl(struct drm_device *dev, void *data,
+                         struct drm_file *file)
 {
        struct drm_i915_gem_execbuffer *args = data;
        struct drm_i915_gem_execbuffer2 exec2;
@@ -2554,8 +2556,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
 }
 
 int
-i915_gem_execbuffer2(struct drm_device *dev, void *data,
-                    struct drm_file *file)
+i915_gem_execbuffer2_ioctl(struct drm_device *dev, void *data,
+                          struct drm_file *file)
 {
        struct drm_i915_gem_execbuffer2 *args = data;
        struct drm_i915_gem_exec_object2 *exec2_list;
index b8338d75c6f3faca71003de6b12ab25eba983562..d548ac05ccd7a45994f38960dd121e79b4d6ecf9 100644 (file)
@@ -64,7 +64,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *fence,
        int fence_pitch_shift;
        u64 val;
 
-       if (INTEL_INFO(fence->i915)->gen >= 6) {
+       if (INTEL_GEN(fence->i915) >= 6) {
                fence_reg_lo = FENCE_REG_GEN6_LO(fence->id);
                fence_reg_hi = FENCE_REG_GEN6_HI(fence->id);
                fence_pitch_shift = GEN6_FENCE_PITCH_SHIFT;
index 955ce7bee448384709d99a7eece4d7560d9e59fe..cd5984246bc34ff5278f27243f695fab7a0c7ff1 100644 (file)
@@ -673,27 +673,22 @@ static void free_pd(struct i915_address_space *vm,
 static void gen8_initialize_pd(struct i915_address_space *vm,
                               struct i915_page_directory *pd)
 {
-       unsigned int i;
-
        fill_px(vm, pd,
                gen8_pde_encode(px_dma(vm->scratch_pt), I915_CACHE_LLC));
-       for (i = 0; i < I915_PDES; i++)
-               pd->page_table[i] = vm->scratch_pt;
+       memset_p((void **)pd->page_table, vm->scratch_pt, I915_PDES);
 }
 
 static int __pdp_init(struct i915_address_space *vm,
                      struct i915_page_directory_pointer *pdp)
 {
        const unsigned int pdpes = i915_pdpes_per_pdp(vm);
-       unsigned int i;
 
        pdp->page_directory = kmalloc_array(pdpes, sizeof(*pdp->page_directory),
                                            GFP_KERNEL | __GFP_NOWARN);
        if (unlikely(!pdp->page_directory))
                return -ENOMEM;
 
-       for (i = 0; i < pdpes; i++)
-               pdp->page_directory[i] = vm->scratch_pd;
+       memset_p((void **)pdp->page_directory, vm->scratch_pd, pdpes);
 
        return 0;
 }
@@ -715,7 +710,7 @@ alloc_pdp(struct i915_address_space *vm)
        struct i915_page_directory_pointer *pdp;
        int ret = -ENOMEM;
 
-       WARN_ON(!use_4lvl(vm));
+       GEM_BUG_ON(!use_4lvl(vm));
 
        pdp = kzalloc(sizeof(*pdp), GFP_KERNEL);
        if (!pdp)
@@ -764,12 +759,9 @@ static void gen8_initialize_pdp(struct i915_address_space *vm,
 static void gen8_initialize_pml4(struct i915_address_space *vm,
                                 struct i915_pml4 *pml4)
 {
-       unsigned int i;
-
        fill_px(vm, pml4,
                gen8_pml4e_encode(px_dma(vm->scratch_pdp), I915_CACHE_LLC));
-       for (i = 0; i < GEN8_PML4ES_PER_PML4; i++)
-               pml4->pdps[i] = vm->scratch_pdp;
+       memset_p((void **)pml4->pdps, vm->scratch_pdp, GEN8_PML4ES_PER_PML4);
 }
 
 /* Broadwell Page Directory Pointer Descriptors */
@@ -2109,7 +2101,7 @@ static int __hw_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
        ppgtt->base.i915 = dev_priv;
        ppgtt->base.dma = &dev_priv->drm.pdev->dev;
 
-       if (INTEL_INFO(dev_priv)->gen < 8)
+       if (INTEL_GEN(dev_priv) < 8)
                return gen6_ppgtt_init(ppgtt);
        else
                return gen8_ppgtt_init(ppgtt);
@@ -2257,9 +2249,9 @@ void i915_ppgtt_release(struct kref *kref)
        trace_i915_ppgtt_release(&ppgtt->base);
 
        /* vmas should already be unbound and destroyed */
-       WARN_ON(!list_empty(&ppgtt->base.active_list));
-       WARN_ON(!list_empty(&ppgtt->base.inactive_list));
-       WARN_ON(!list_empty(&ppgtt->base.unbound_list));
+       GEM_BUG_ON(!list_empty(&ppgtt->base.active_list));
+       GEM_BUG_ON(!list_empty(&ppgtt->base.inactive_list));
+       GEM_BUG_ON(!list_empty(&ppgtt->base.unbound_list));
 
        ppgtt->base.cleanup(&ppgtt->base);
        i915_address_space_fini(&ppgtt->base);
@@ -2822,10 +2814,10 @@ int i915_gem_init_aliasing_ppgtt(struct drm_i915_private *i915)
 
        i915->mm.aliasing_ppgtt = ppgtt;
 
-       WARN_ON(ggtt->base.bind_vma != ggtt_bind_vma);
+       GEM_BUG_ON(ggtt->base.bind_vma != ggtt_bind_vma);
        ggtt->base.bind_vma = aliasing_gtt_bind_vma;
 
-       WARN_ON(ggtt->base.unbind_vma != ggtt_unbind_vma);
+       GEM_BUG_ON(ggtt->base.unbind_vma != ggtt_unbind_vma);
        ggtt->base.unbind_vma = aliasing_gtt_unbind_vma;
 
        return 0;
@@ -2916,7 +2908,7 @@ void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv)
        ggtt->base.closed = true;
 
        mutex_lock(&dev_priv->drm.struct_mutex);
-       WARN_ON(!list_empty(&ggtt->base.active_list));
+       GEM_BUG_ON(!list_empty(&ggtt->base.active_list));
        list_for_each_entry_safe(vma, vn, &ggtt->base.inactive_list, vm_link)
                WARN_ON(i915_vma_unbind(vma));
        mutex_unlock(&dev_priv->drm.struct_mutex);
@@ -3809,6 +3801,9 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
        GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
 
        switch (vma->ggtt_view.type) {
+       default:
+               GEM_BUG_ON(vma->ggtt_view.type);
+               /* fall through */
        case I915_GGTT_VIEW_NORMAL:
                vma->pages = vma->obj->mm.pages;
                return 0;
@@ -3821,11 +3816,6 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
        case I915_GGTT_VIEW_PARTIAL:
                vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
                break;
-
-       default:
-               WARN_ONCE(1, "GGTT view %u not implemented!\n",
-                         vma->ggtt_view.type);
-               return -EINVAL;
        }
 
        ret = 0;
index a1d6956734f75ede865dbd98fa03bd8555b207a2..0d0144b2104cb3264b2048a1569bc598fde532f3 100644 (file)
@@ -167,6 +167,10 @@ static const struct drm_i915_gem_object_ops i915_gem_object_internal_ops = {
 };
 
 /**
+ * i915_gem_object_create_internal: create an object with volatile pages
+ * @i915: the i915 device
+ * @size: the size in bytes of backing storage to allocate for the object
+ *
  * Creates a new object that wraps some internal memory for private use.
  * This object is not backed by swappable storage, and as such its contents
  * are volatile and only valid whilst pinned. If the object is reaped by the
@@ -197,8 +201,8 @@ i915_gem_object_create_internal(struct drm_i915_private *i915,
        drm_gem_private_object_init(&i915->drm, &obj->base, size);
        i915_gem_object_init(obj, &i915_gem_object_internal_ops);
 
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU;
-       obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+       obj->read_domains = I915_GEM_DOMAIN_CPU;
+       obj->write_domain = I915_GEM_DOMAIN_CPU;
 
        cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
        i915_gem_object_set_cache_coherency(obj, cache_level);
index 05e89e1c0a088b6cc2ca9e28f0d4ddd606726f97..ca2b3b62569d1475de2370fd5cffc138aaf17a3f 100644 (file)
@@ -148,6 +148,21 @@ struct drm_i915_gem_object {
 #define I915_BO_CACHE_COHERENT_FOR_WRITE BIT(1)
        unsigned int cache_dirty:1;
 
+       /**
+        * @read_domains: Read memory domains.
+        *
+        * These monitor which caches contain read/write data related to the
+        * object. When transitioning from one set of domains to another,
+        * the driver is called to ensure that caches are suitably flushed and
+        * invalidated.
+        */
+       u16 read_domains;
+
+       /**
+        * @write_domain: Corresponding unique write memory domain.
+        */
+       u16 write_domain;
+
        atomic_t frontbuffer_bits;
        unsigned int frontbuffer_ggtt_origin; /* write once */
        struct i915_gem_active frontbuffer_write;
index 8efa9e7a9e4672a04857d7c154ef258c2c2687dd..8bc7c50b84189107b0ae04b1bbadf108e5816ccc 100644 (file)
@@ -443,12 +443,14 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
        engine->last_retired_context = request->ctx;
 
        spin_lock_irq(&request->lock);
-       if (request->waitboost)
-               atomic_dec(&request->i915->gt_pm.rps.num_waiters);
        if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags))
                dma_fence_signal_locked(&request->fence);
        if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags))
                intel_engine_cancel_signaling(request);
+       if (request->waitboost) {
+               GEM_BUG_ON(!atomic_read(&request->i915->gt_pm.rps.num_waiters));
+               atomic_dec(&request->i915->gt_pm.rps.num_waiters);
+       }
        spin_unlock_irq(&request->lock);
 
        i915_priotree_fini(request->i915, &request->priotree);
@@ -916,9 +918,9 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
 
 /**
  * i915_gem_request_await_object - set this request to (async) wait upon a bo
- *
  * @to: request we are wishing to use
  * @obj: object which may be in use on another ring.
+ * @write: whether the wait is on behalf of a writer
  *
  * This code is meant to abstract object synchronization with the GPU.
  * Conceptually we serialise writes between engines inside the GPU.
@@ -993,7 +995,8 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
        lockdep_assert_held(&request->i915->drm.struct_mutex);
        trace_i915_gem_request_add(request);
 
-       /* Make sure that no request gazumped us - if it was allocated after
+       /*
+        * Make sure that no request gazumped us - if it was allocated after
         * our i915_gem_request_alloc() and called __i915_add_request() before
         * us, the timeline will hold its seqno which is later than ours.
         */
@@ -1020,7 +1023,8 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
                WARN(err, "engine->emit_flush() failed: %d!\n", err);
        }
 
-       /* Record the position of the start of the breadcrumb so that
+       /*
+        * Record the position of the start of the breadcrumb so that
         * should we detect the updated seqno part-way through the
         * GPU processing the request, we never over-estimate the
         * position of the ring's HEAD.
@@ -1029,7 +1033,8 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
        GEM_BUG_ON(IS_ERR(cs));
        request->postfix = intel_ring_offset(request, cs);
 
-       /* Seal the request and mark it as pending execution. Note that
+       /*
+        * Seal the request and mark it as pending execution. Note that
         * we may inspect this state, without holding any locks, during
         * hangcheck. Hence we apply the barrier to ensure that we do not
         * see a more recent value in the hws than we are tracking.
@@ -1037,7 +1042,7 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
 
        prev = i915_gem_active_raw(&timeline->last_request,
                                   &request->i915->drm.struct_mutex);
-       if (prev) {
+       if (prev && !i915_gem_request_completed(prev)) {
                i915_sw_fence_await_sw_fence(&request->submit, &prev->submit,
                                             &request->submitq);
                if (engine->schedule)
@@ -1057,7 +1062,8 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
        list_add_tail(&request->ring_link, &ring->request_list);
        request->emitted_jiffies = jiffies;
 
-       /* Let the backend know a new request has arrived that may need
+       /*
+        * Let the backend know a new request has arrived that may need
         * to adjust the existing execution schedule due to a high priority
         * request - i.e. we may want to preempt the current request in order
         * to run a high priority dependency chain *before* we can execute this
@@ -1073,6 +1079,26 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches)
        local_bh_disable();
        i915_sw_fence_commit(&request->submit);
        local_bh_enable(); /* Kick the execlists tasklet if just scheduled */
+
+       /*
+        * In typical scenarios, we do not expect the previous request on
+        * the timeline to be still tracked by timeline->last_request if it
+        * has been completed. If the completed request is still here, that
+        * implies that request retirement is a long way behind submission,
+        * suggesting that we haven't been retiring frequently enough from
+        * the combination of retire-before-alloc, waiters and the background
+        * retirement worker. So if the last request on this timeline was
+        * already completed, do a catch up pass, flushing the retirement queue
+        * up to this client. Since we have now moved the heaviest operations
+        * during retirement onto secondary workers, such as freeing objects
+        * or contexts, retiring a bunch of requests is mostly list management
+        * (and cache misses), and so we should not be overly penalizing this
+        * client by performing excess work, though we may still performing
+        * work on behalf of others -- but instead we should benefit from
+        * improved resource management. (Well, that's the theory at least.)
+        */
+       if (prev && i915_gem_request_completed(prev))
+               i915_gem_request_retire_upto(prev);
 }
 
 static unsigned long local_clock_us(unsigned int *cpu)
index d3f222fa6356d53d70c0bb37ea46e0a56c0c03b3..62aa67960bf4ceabcb7bed46e51175b12989604f 100644 (file)
@@ -356,7 +356,7 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv)
        reserved_base = 0;
        reserved_size = 0;
 
-       switch (INTEL_INFO(dev_priv)->gen) {
+       switch (INTEL_GEN(dev_priv)) {
        case 2:
        case 3:
                break;
@@ -516,7 +516,7 @@ _i915_gem_object_create_stolen(struct drm_i915_private *dev_priv,
        i915_gem_object_init(obj, &i915_gem_object_stolen_ops);
 
        obj->stolen = stolen;
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
+       obj->read_domains = I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT;
        cache_level = HAS_LLC(dev_priv) ? I915_CACHE_LLC : I915_CACHE_NONE;
        i915_gem_object_set_cache_coherency(obj, cache_level);
 
index 382a77a1097e735468558415d3fa860afbb8c818..d596a8302ca3cca529977a10ebc02965855525af 100644 (file)
@@ -721,7 +721,7 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
        .release = i915_gem_userptr_release,
 };
 
-/**
+/*
  * Creates a new mm object that wraps some normal memory from the process
  * context - user memory.
  *
@@ -757,7 +757,9 @@ static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = {
  * dma-buf instead.
  */
 int
-i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
+i915_gem_userptr_ioctl(struct drm_device *dev,
+                      void *data,
+                      struct drm_file *file)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_i915_gem_userptr *args = data;
@@ -796,8 +798,8 @@ i915_gem_userptr_ioctl(struct drm_device *dev, void *data, struct drm_file *file
 
        drm_gem_private_object_init(dev, &obj->base, args->user_size);
        i915_gem_object_init(obj, &i915_gem_userptr_ops);
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU;
-       obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+       obj->read_domains = I915_GEM_DOMAIN_CPU;
+       obj->write_domain = I915_GEM_DOMAIN_CPU;
        i915_gem_object_set_cache_coherency(obj, I915_CACHE_LLC);
 
        obj->userptr.ptr = args->user_ptr;
index 67c902412193d452a103016971eeb2a555b066ad..65c0bef73ee5af252125fc6f1e6216d8817f39b9 100644 (file)
@@ -579,11 +579,13 @@ static void print_error_obj(struct drm_i915_error_state_buf *m,
 }
 
 static void err_print_capabilities(struct drm_i915_error_state_buf *m,
-                                  const struct intel_device_info *info)
+                                  const struct intel_device_info *info,
+                                  const struct intel_driver_caps *caps)
 {
        struct drm_printer p = i915_error_printer(m);
 
        intel_device_info_dump_flags(info, &p);
+       intel_driver_caps_print(caps, &p);
 }
 
 static void err_print_params(struct drm_i915_error_state_buf *m,
@@ -808,7 +810,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
        if (error->display)
                intel_display_print_error_state(m, error->display);
 
-       err_print_capabilities(m, &error->device_info);
+       err_print_capabilities(m, &error->device_info, &error->driver_caps);
        err_print_params(m, &error->params);
        err_print_uc(m, &error->uc);
 
@@ -1019,8 +1021,8 @@ static void capture_bo(struct drm_i915_error_buffer *err,
        err->engine = __active_get_engine_id(&obj->frontbuffer_write);
 
        err->gtt_offset = vma->node.start;
-       err->read_domains = obj->base.read_domains;
-       err->write_domain = obj->base.write_domain;
+       err->read_domains = obj->read_domains;
+       err->write_domain = obj->write_domain;
        err->fence_reg = vma->fence ? vma->fence->id : -1;
        err->tiling = i915_gem_object_get_tiling(obj);
        err->dirty = obj->mm.dirty;
@@ -1740,6 +1742,7 @@ static void i915_capture_gen_state(struct drm_i915_private *dev_priv,
        memcpy(&error->device_info,
               INTEL_INFO(dev_priv),
               sizeof(error->device_info));
+       error->driver_caps = dev_priv->caps;
 }
 
 static __always_inline void dup_param(const char *type, void *x)
@@ -1802,14 +1805,16 @@ i915_capture_gpu_state(struct drm_i915_private *i915)
 
 /**
  * i915_capture_error_state - capture an error record for later analysis
- * @dev: drm device
+ * @i915: i915 device
+ * @engine_mask: the mask of engines triggering the hang
+ * @error_msg: a message to insert into the error capture header
  *
  * Should be called when an error is detected (either a hang or an error
  * interrupt) to capture error state from the time of the error.  Fills
  * out a structure which becomes available in debugfs for user level tools
  * to pick up.
  */
-void i915_capture_error_state(struct drm_i915_private *dev_priv,
+void i915_capture_error_state(struct drm_i915_private *i915,
                              u32 engine_mask,
                              const char *error_msg)
 {
@@ -1820,25 +1825,25 @@ void i915_capture_error_state(struct drm_i915_private *dev_priv,
        if (!i915_modparams.error_capture)
                return;
 
-       if (READ_ONCE(dev_priv->gpu_error.first_error))
+       if (READ_ONCE(i915->gpu_error.first_error))
                return;
 
-       error = i915_capture_gpu_state(dev_priv);
+       error = i915_capture_gpu_state(i915);
        if (!error) {
                DRM_DEBUG_DRIVER("out of memory, not capturing error state\n");
                return;
        }
 
-       i915_error_capture_msg(dev_priv, error, engine_mask, error_msg);
+       i915_error_capture_msg(i915, error, engine_mask, error_msg);
        DRM_INFO("%s\n", error->error_msg);
 
        if (!error->simulated) {
-               spin_lock_irqsave(&dev_priv->gpu_error.lock, flags);
-               if (!dev_priv->gpu_error.first_error) {
-                       dev_priv->gpu_error.first_error = error;
+               spin_lock_irqsave(&i915->gpu_error.lock, flags);
+               if (!i915->gpu_error.first_error) {
+                       i915->gpu_error.first_error = error;
                        error = NULL;
                }
-               spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags);
+               spin_unlock_irqrestore(&i915->gpu_error.lock, flags);
        }
 
        if (error) {
@@ -1853,7 +1858,7 @@ void i915_capture_error_state(struct drm_i915_private *dev_priv,
                DRM_INFO("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n");
                DRM_INFO("The gpu crash dump is required to analyze gpu hangs, so please always attach it.\n");
                DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n",
-                        dev_priv->drm.primary->index);
+                        i915->drm.primary->index);
                warned = true;
        }
 }
index 97f3a5640289389a8328ac66da9e127c7a3ed6c6..0e5c580d117cfcced6254ddab4dfcec04611bea9 100644 (file)
@@ -1,11 +1,6 @@
-/**
- * \file i915_ioc32.c
- *
+/*
  * 32-bit ioctl compatibility routines for the i915 DRM.
  *
- * \author Alan Hourihane <alanh@fairlite.demon.co.uk>
- *
- *
  * Copyright (C) Paul Mackerras 2005
  * Copyright (C) Alan Hourihane 2005
  * All Rights Reserved.
@@ -28,6 +23,8 @@
  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  * IN THE SOFTWARE.
+ *
+ * Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
  */
 #include <linux/compat.h>
 
@@ -55,10 +52,10 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd,
                return -EFAULT;
 
        request = compat_alloc_user_space(sizeof(*request));
-       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
-           || __put_user(req32.param, &request->param)
-           || __put_user((void __user *)(unsigned long)req32.value,
-                         &request->value))
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) ||
+           __put_user(req32.param, &request->param) ||
+           __put_user((void __user *)(unsigned long)req32.value,
+                      &request->value))
                return -EFAULT;
 
        return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,
@@ -70,13 +67,13 @@ static drm_ioctl_compat_t *i915_compat_ioctls[] = {
 };
 
 /**
+ * i915_compat_ioctl - handle the mistakes of the past
+ * @filp: the file pointer
+ * @cmd: the ioctl command (and encoded flags)
+ * @arg: the ioctl argument (from userspace)
+ *
  * Called whenever a 32-bit process running under a 64-bit kernel
  * performs an ioctl on /dev/dri/card<n>.
- *
- * \param filp file pointer.
- * \param cmd command.
- * \param arg user argument.
- * \return zero on success or negative number on failure.
  */
 long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
index b886bd459acc5c097cbed8d0293a129147a2d30c..17de6cef2a3076795b0f4f337ccd6fbe0055f043 100644 (file)
@@ -1413,64 +1413,73 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir, int test_shift)
                tasklet_hi_schedule(&execlists->tasklet);
 }
 
-static void gen8_gt_irq_ack(struct drm_i915_private *dev_priv,
+static void gen8_gt_irq_ack(struct drm_i915_private *i915,
                            u32 master_ctl, u32 gt_iir[4])
 {
+       void __iomem * const regs = i915->regs;
+
+#define GEN8_GT_IRQS (GEN8_GT_RCS_IRQ | \
+                     GEN8_GT_BCS_IRQ | \
+                     GEN8_GT_VCS1_IRQ | \
+                     GEN8_GT_VCS2_IRQ | \
+                     GEN8_GT_VECS_IRQ | \
+                     GEN8_GT_PM_IRQ | \
+                     GEN8_GT_GUC_IRQ)
+
        if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
-               gt_iir[0] = I915_READ_FW(GEN8_GT_IIR(0));
-               if (gt_iir[0])
-                       I915_WRITE_FW(GEN8_GT_IIR(0), gt_iir[0]);
+               gt_iir[0] = raw_reg_read(regs, GEN8_GT_IIR(0));
+               if (likely(gt_iir[0]))
+                       raw_reg_write(regs, GEN8_GT_IIR(0), gt_iir[0]);
        }
 
        if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) {
-               gt_iir[1] = I915_READ_FW(GEN8_GT_IIR(1));
-               if (gt_iir[1])
-                       I915_WRITE_FW(GEN8_GT_IIR(1), gt_iir[1]);
+               gt_iir[1] = raw_reg_read(regs, GEN8_GT_IIR(1));
+               if (likely(gt_iir[1]))
+                       raw_reg_write(regs, GEN8_GT_IIR(1), gt_iir[1]);
        }
 
-       if (master_ctl & GEN8_GT_VECS_IRQ) {
-               gt_iir[3] = I915_READ_FW(GEN8_GT_IIR(3));
-               if (gt_iir[3])
-                       I915_WRITE_FW(GEN8_GT_IIR(3), gt_iir[3]);
+       if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) {
+               gt_iir[2] = raw_reg_read(regs, GEN8_GT_IIR(2));
+               if (likely(gt_iir[2] & (i915->pm_rps_events |
+                                       i915->pm_guc_events)))
+                       raw_reg_write(regs, GEN8_GT_IIR(2),
+                                     gt_iir[2] & (i915->pm_rps_events |
+                                                  i915->pm_guc_events));
        }
 
-       if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) {
-               gt_iir[2] = I915_READ_FW(GEN8_GT_IIR(2));
-               if (gt_iir[2] & (dev_priv->pm_rps_events |
-                                dev_priv->pm_guc_events)) {
-                       I915_WRITE_FW(GEN8_GT_IIR(2),
-                                     gt_iir[2] & (dev_priv->pm_rps_events |
-                                                  dev_priv->pm_guc_events));
-               }
+       if (master_ctl & GEN8_GT_VECS_IRQ) {
+               gt_iir[3] = raw_reg_read(regs, GEN8_GT_IIR(3));
+               if (likely(gt_iir[3]))
+                       raw_reg_write(regs, GEN8_GT_IIR(3), gt_iir[3]);
        }
 }
 
-static void gen8_gt_irq_handler(struct drm_i915_private *dev_priv,
-                               u32 gt_iir[4])
+static void gen8_gt_irq_handler(struct drm_i915_private *i915,
+                               u32 master_ctl, u32 gt_iir[4])
 {
-       if (gt_iir[0]) {
-               gen8_cs_irq_handler(dev_priv->engine[RCS],
+       if (master_ctl & (GEN8_GT_RCS_IRQ | GEN8_GT_BCS_IRQ)) {
+               gen8_cs_irq_handler(i915->engine[RCS],
                                    gt_iir[0], GEN8_RCS_IRQ_SHIFT);
-               gen8_cs_irq_handler(dev_priv->engine[BCS],
+               gen8_cs_irq_handler(i915->engine[BCS],
                                    gt_iir[0], GEN8_BCS_IRQ_SHIFT);
        }
 
-       if (gt_iir[1]) {
-               gen8_cs_irq_handler(dev_priv->engine[VCS],
+       if (master_ctl & (GEN8_GT_VCS1_IRQ | GEN8_GT_VCS2_IRQ)) {
+               gen8_cs_irq_handler(i915->engine[VCS],
                                    gt_iir[1], GEN8_VCS1_IRQ_SHIFT);
-               gen8_cs_irq_handler(dev_priv->engine[VCS2],
+               gen8_cs_irq_handler(i915->engine[VCS2],
                                    gt_iir[1], GEN8_VCS2_IRQ_SHIFT);
        }
 
-       if (gt_iir[3])
-               gen8_cs_irq_handler(dev_priv->engine[VECS],
+       if (master_ctl & GEN8_GT_VECS_IRQ) {
+               gen8_cs_irq_handler(i915->engine[VECS],
                                    gt_iir[3], GEN8_VECS_IRQ_SHIFT);
+       }
 
-       if (gt_iir[2] & dev_priv->pm_rps_events)
-               gen6_rps_irq_handler(dev_priv, gt_iir[2]);
-
-       if (gt_iir[2] & dev_priv->pm_guc_events)
-               gen9_guc_irq_handler(dev_priv, gt_iir[2]);
+       if (master_ctl & (GEN8_GT_PM_IRQ | GEN8_GT_GUC_IRQ)) {
+               gen6_rps_irq_handler(i915, gt_iir[2]);
+               gen9_guc_irq_handler(i915, gt_iir[2]);
+       }
 }
 
 static bool bxt_port_hotplug_long_detect(enum port port, u32 val)
@@ -2085,9 +2094,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
 
        do {
                u32 master_ctl, iir;
-               u32 gt_iir[4] = {};
                u32 pipe_stats[I915_MAX_PIPES] = {};
                u32 hotplug_status = 0;
+               u32 gt_iir[4];
                u32 ier = 0;
 
                master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
@@ -2140,7 +2149,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
                I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
                POSTING_READ(GEN8_MASTER_IRQ);
 
-               gen8_gt_irq_handler(dev_priv, gt_iir);
+               gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
 
                if (hotplug_status)
                        i9xx_hpd_irq_handler(dev_priv, hotplug_status);
@@ -2675,10 +2684,9 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
 
 static irqreturn_t gen8_irq_handler(int irq, void *arg)
 {
-       struct drm_device *dev = arg;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(arg);
        u32 master_ctl;
-       u32 gt_iir[4] = {};
+       u32 gt_iir[4];
 
        if (!intel_irqs_enabled(dev_priv))
                return IRQ_NONE;
@@ -2690,18 +2698,19 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 
        I915_WRITE_FW(GEN8_MASTER_IRQ, 0);
 
-       /* IRQs are synced during runtime_suspend, we don't require a wakeref */
-       disable_rpm_wakeref_asserts(dev_priv);
-
        /* Find, clear, then process each source of interrupt */
        gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
-       gen8_gt_irq_handler(dev_priv, gt_iir);
-       gen8_de_irq_handler(dev_priv, master_ctl);
+
+       /* IRQs are synced during runtime_suspend, we don't require a wakeref */
+       if (master_ctl & ~GEN8_GT_IRQS) {
+               disable_rpm_wakeref_asserts(dev_priv);
+               gen8_de_irq_handler(dev_priv, master_ctl);
+               enable_rpm_wakeref_asserts(dev_priv);
+       }
 
        I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
-       POSTING_READ_FW(GEN8_MASTER_IRQ);
 
-       enable_rpm_wakeref_asserts(dev_priv);
+       gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
 
        return IRQ_HANDLED;
 }
@@ -2951,6 +2960,12 @@ static int ironlake_enable_vblank(struct drm_device *dev, unsigned int pipe)
        ilk_enable_display_irq(dev_priv, bit);
        spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 
+       /* Even though there is no DMC, frame counter can get stuck when
+        * PSR is active as no frames are generated.
+        */
+       if (HAS_PSR(dev_priv))
+               drm_vblank_restore(dev, pipe);
+
        return 0;
 }
 
@@ -2963,6 +2978,12 @@ static int gen8_enable_vblank(struct drm_device *dev, unsigned int pipe)
        bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
        spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 
+       /* Even if there is no DMC, frame counter can get stuck when
+        * PSR is active as no frames are generated, so check only for PSR.
+        */
+       if (HAS_PSR(dev_priv))
+               drm_vblank_restore(dev, pipe);
+
        return 0;
 }
 
index 42ff06fe54a3a89b4e1d50e3ad2a033cc92a786a..792facdb6702bffdcb808f8bc748518c8299ac8e 100644 (file)
@@ -84,9 +84,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_cflgt3(struct drm_i915_private *dev_priv)
 {
-       strncpy(dev_priv->perf.oa.test_config.uuid,
+       strlcpy(dev_priv->perf.oa.test_config.uuid,
                "577e8e2c-3fa0-4875-8743-3538d585e3b0",
-               UUID_STRING_LEN);
+               sizeof(dev_priv->perf.oa.test_config.uuid));
        dev_priv->perf.oa.test_config.id = 1;
 
        dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
index ff0ac3627cc4bc73858d6c71df9b9571a27de4df..ba9140c87cc0ba7de03f0c36ef91ebcaf372b4c8 100644 (file)
@@ -96,9 +96,9 @@ show_test_oa_id(struct device *kdev, struct device_attribute *attr, char *buf)
 void
 i915_perf_load_test_config_cnl(struct drm_i915_private *dev_priv)
 {
-       strncpy(dev_priv->perf.oa.test_config.uuid,
+       strlcpy(dev_priv->perf.oa.test_config.uuid,
                "db41edd4-d8e7-4730-ad11-b9a2d6833503",
-               UUID_STRING_LEN);
+               sizeof(dev_priv->perf.oa.test_config.uuid));
        dev_priv->perf.oa.test_config.id = 1;
 
        dev_priv->perf.oa.test_config.mux_regs = mux_config_test_oa;
index 4e7a10c897829201619522e1dfff1696d05881b9..1eaabf28d7b70ce8d69fd312f206c7eea6b56073 100644 (file)
@@ -29,6 +29,9 @@
 #include "i915_drv.h"
 #include "i915_selftest.h"
 
+#define PLATFORM(x) .platform = (x), .platform_mask = BIT(x)
+#define GEN(x) .gen = (x), .gen_mask = BIT((x) - 1)
+
 #define GEN_DEFAULT_PIPEOFFSETS \
        .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \
                          PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \
@@ -63,7 +66,8 @@
        .page_sizes = I915_GTT_PAGE_SIZE_4K
 
 #define GEN2_FEATURES \
-       .gen = 2, .num_pipes = 1, \
+       GEN(2), \
+       .num_pipes = 1, \
        .has_overlay = 1, .overlay_needs_physical = 1, \
        .has_gmch_display = 1, \
        .hws_needs_physical = 1, \
 
 static const struct intel_device_info intel_i830_info = {
        GEN2_FEATURES,
-       .platform = INTEL_I830,
+       PLATFORM(INTEL_I830),
        .is_mobile = 1, .cursor_needs_physical = 1,
        .num_pipes = 2, /* legal, last one wins */
 };
 
 static const struct intel_device_info intel_i845g_info = {
        GEN2_FEATURES,
-       .platform = INTEL_I845G,
+       PLATFORM(INTEL_I845G),
 };
 
 static const struct intel_device_info intel_i85x_info = {
        GEN2_FEATURES,
-       .platform = INTEL_I85X, .is_mobile = 1,
+       PLATFORM(INTEL_I85X),
+       .is_mobile = 1,
        .num_pipes = 2, /* legal, last one wins */
        .cursor_needs_physical = 1,
        .has_fbc = 1,
@@ -96,11 +101,12 @@ static const struct intel_device_info intel_i85x_info = {
 
 static const struct intel_device_info intel_i865g_info = {
        GEN2_FEATURES,
-       .platform = INTEL_I865G,
+       PLATFORM(INTEL_I865G),
 };
 
 #define GEN3_FEATURES \
-       .gen = 3, .num_pipes = 2, \
+       GEN(3), \
+       .num_pipes = 2, \
        .has_gmch_display = 1, \
        .ring_mask = RENDER_RING, \
        .has_snoop = true, \
@@ -110,7 +116,8 @@ static const struct intel_device_info intel_i865g_info = {
 
 static const struct intel_device_info intel_i915g_info = {
        GEN3_FEATURES,
-       .platform = INTEL_I915G, .cursor_needs_physical = 1,
+       PLATFORM(INTEL_I915G),
+       .cursor_needs_physical = 1,
        .has_overlay = 1, .overlay_needs_physical = 1,
        .hws_needs_physical = 1,
        .unfenced_needs_alignment = 1,
@@ -118,7 +125,7 @@ static const struct intel_device_info intel_i915g_info = {
 
 static const struct intel_device_info intel_i915gm_info = {
        GEN3_FEATURES,
-       .platform = INTEL_I915GM,
+       PLATFORM(INTEL_I915GM),
        .is_mobile = 1,
        .cursor_needs_physical = 1,
        .has_overlay = 1, .overlay_needs_physical = 1,
@@ -130,7 +137,7 @@ static const struct intel_device_info intel_i915gm_info = {
 
 static const struct intel_device_info intel_i945g_info = {
        GEN3_FEATURES,
-       .platform = INTEL_I945G,
+       PLATFORM(INTEL_I945G),
        .has_hotplug = 1, .cursor_needs_physical = 1,
        .has_overlay = 1, .overlay_needs_physical = 1,
        .hws_needs_physical = 1,
@@ -139,7 +146,8 @@ static const struct intel_device_info intel_i945g_info = {
 
 static const struct intel_device_info intel_i945gm_info = {
        GEN3_FEATURES,
-       .platform = INTEL_I945GM, .is_mobile = 1,
+       PLATFORM(INTEL_I945GM),
+       .is_mobile = 1,
        .has_hotplug = 1, .cursor_needs_physical = 1,
        .has_overlay = 1, .overlay_needs_physical = 1,
        .supports_tv = 1,
@@ -150,20 +158,22 @@ static const struct intel_device_info intel_i945gm_info = {
 
 static const struct intel_device_info intel_g33_info = {
        GEN3_FEATURES,
-       .platform = INTEL_G33,
+       PLATFORM(INTEL_G33),
        .has_hotplug = 1,
        .has_overlay = 1,
 };
 
 static const struct intel_device_info intel_pineview_info = {
        GEN3_FEATURES,
-       .platform = INTEL_PINEVIEW, .is_mobile = 1,
+       PLATFORM(INTEL_PINEVIEW),
+       .is_mobile = 1,
        .has_hotplug = 1,
        .has_overlay = 1,
 };
 
 #define GEN4_FEATURES \
-       .gen = 4, .num_pipes = 2, \
+       GEN(4), \
+       .num_pipes = 2, \
        .has_hotplug = 1, \
        .has_gmch_display = 1, \
        .ring_mask = RENDER_RING, \
@@ -174,7 +184,7 @@ static const struct intel_device_info intel_pineview_info = {
 
 static const struct intel_device_info intel_i965g_info = {
        GEN4_FEATURES,
-       .platform = INTEL_I965G,
+       PLATFORM(INTEL_I965G),
        .has_overlay = 1,
        .hws_needs_physical = 1,
        .has_snoop = false,
@@ -182,7 +192,7 @@ static const struct intel_device_info intel_i965g_info = {
 
 static const struct intel_device_info intel_i965gm_info = {
        GEN4_FEATURES,
-       .platform = INTEL_I965GM,
+       PLATFORM(INTEL_I965GM),
        .is_mobile = 1, .has_fbc = 1,
        .has_overlay = 1,
        .supports_tv = 1,
@@ -192,20 +202,21 @@ static const struct intel_device_info intel_i965gm_info = {
 
 static const struct intel_device_info intel_g45_info = {
        GEN4_FEATURES,
-       .platform = INTEL_G45,
+       PLATFORM(INTEL_G45),
        .ring_mask = RENDER_RING | BSD_RING,
 };
 
 static const struct intel_device_info intel_gm45_info = {
        GEN4_FEATURES,
-       .platform = INTEL_GM45,
+       PLATFORM(INTEL_GM45),
        .is_mobile = 1, .has_fbc = 1,
        .supports_tv = 1,
        .ring_mask = RENDER_RING | BSD_RING,
 };
 
 #define GEN5_FEATURES \
-       .gen = 5, .num_pipes = 2, \
+       GEN(5), \
+       .num_pipes = 2, \
        .has_hotplug = 1, \
        .ring_mask = RENDER_RING | BSD_RING, \
        .has_snoop = true, \
@@ -217,17 +228,18 @@ static const struct intel_device_info intel_gm45_info = {
 
 static const struct intel_device_info intel_ironlake_d_info = {
        GEN5_FEATURES,
-       .platform = INTEL_IRONLAKE,
+       PLATFORM(INTEL_IRONLAKE),
 };
 
 static const struct intel_device_info intel_ironlake_m_info = {
        GEN5_FEATURES,
-       .platform = INTEL_IRONLAKE,
+       PLATFORM(INTEL_IRONLAKE),
        .is_mobile = 1, .has_fbc = 1,
 };
 
 #define GEN6_FEATURES \
-       .gen = 6, .num_pipes = 2, \
+       GEN(6), \
+       .num_pipes = 2, \
        .has_hotplug = 1, \
        .has_fbc = 1, \
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \
@@ -241,7 +253,7 @@ static const struct intel_device_info intel_ironlake_m_info = {
 
 #define SNB_D_PLATFORM \
        GEN6_FEATURES, \
-       .platform = INTEL_SANDYBRIDGE
+       PLATFORM(INTEL_SANDYBRIDGE)
 
 static const struct intel_device_info intel_sandybridge_d_gt1_info = {
        SNB_D_PLATFORM,
@@ -255,7 +267,7 @@ static const struct intel_device_info intel_sandybridge_d_gt2_info = {
 
 #define SNB_M_PLATFORM \
        GEN6_FEATURES, \
-       .platform = INTEL_SANDYBRIDGE, \
+       PLATFORM(INTEL_SANDYBRIDGE), \
        .is_mobile = 1
 
 
@@ -270,7 +282,8 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info = {
 };
 
 #define GEN7_FEATURES  \
-       .gen = 7, .num_pipes = 3, \
+       GEN(7), \
+       .num_pipes = 3, \
        .has_hotplug = 1, \
        .has_fbc = 1, \
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \
@@ -285,7 +298,7 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info = {
 
 #define IVB_D_PLATFORM \
        GEN7_FEATURES, \
-       .platform = INTEL_IVYBRIDGE, \
+       PLATFORM(INTEL_IVYBRIDGE), \
        .has_l3_dpf = 1
 
 static const struct intel_device_info intel_ivybridge_d_gt1_info = {
@@ -300,7 +313,7 @@ static const struct intel_device_info intel_ivybridge_d_gt2_info = {
 
 #define IVB_M_PLATFORM \
        GEN7_FEATURES, \
-       .platform = INTEL_IVYBRIDGE, \
+       PLATFORM(INTEL_IVYBRIDGE), \
        .is_mobile = 1, \
        .has_l3_dpf = 1
 
@@ -316,15 +329,15 @@ static const struct intel_device_info intel_ivybridge_m_gt2_info = {
 
 static const struct intel_device_info intel_ivybridge_q_info = {
        GEN7_FEATURES,
-       .platform = INTEL_IVYBRIDGE,
+       PLATFORM(INTEL_IVYBRIDGE),
        .gt = 2,
        .num_pipes = 0, /* legal, last one wins */
        .has_l3_dpf = 1,
 };
 
 static const struct intel_device_info intel_valleyview_info = {
-       .platform = INTEL_VALLEYVIEW,
-       .gen = 7,
+       PLATFORM(INTEL_VALLEYVIEW),
+       GEN(7),
        .is_lp = 1,
        .num_pipes = 2,
        .has_psr = 1,
@@ -355,7 +368,7 @@ static const struct intel_device_info intel_valleyview_info = {
 
 #define HSW_PLATFORM \
        G75_FEATURES, \
-       .platform = INTEL_HASWELL, \
+       PLATFORM(INTEL_HASWELL), \
        .has_l3_dpf = 1
 
 static const struct intel_device_info intel_haswell_gt1_info = {
@@ -375,6 +388,7 @@ static const struct intel_device_info intel_haswell_gt3_info = {
 
 #define GEN8_FEATURES \
        G75_FEATURES, \
+       GEN(8), \
        BDW_COLORS, \
        .page_sizes = I915_GTT_PAGE_SIZE_4K | \
                      I915_GTT_PAGE_SIZE_2M, \
@@ -385,8 +399,7 @@ static const struct intel_device_info intel_haswell_gt3_info = {
 
 #define BDW_PLATFORM \
        GEN8_FEATURES, \
-       .gen = 8, \
-       .platform = INTEL_BROADWELL
+       PLATFORM(INTEL_BROADWELL)
 
 static const struct intel_device_info intel_broadwell_gt1_info = {
        BDW_PLATFORM,
@@ -413,11 +426,12 @@ static const struct intel_device_info intel_broadwell_gt3_info = {
 };
 
 static const struct intel_device_info intel_cherryview_info = {
-       .gen = 8, .num_pipes = 3,
+       PLATFORM(INTEL_CHERRYVIEW),
+       GEN(8),
+       .num_pipes = 3,
        .has_hotplug = 1,
        .is_lp = 1,
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
-       .platform = INTEL_CHERRYVIEW,
        .has_64bit_reloc = 1,
        .has_psr = 1,
        .has_runtime_pm = 1,
@@ -443,6 +457,7 @@ static const struct intel_device_info intel_cherryview_info = {
 
 #define GEN9_FEATURES \
        GEN8_FEATURES, \
+       GEN(9), \
        GEN9_DEFAULT_PAGE_SIZES, \
        .has_logical_ring_preemption = 1, \
        .has_csr = 1, \
@@ -452,8 +467,7 @@ static const struct intel_device_info intel_cherryview_info = {
 
 #define SKL_PLATFORM \
        GEN9_FEATURES, \
-       .gen = 9, \
-       .platform = INTEL_SKYLAKE
+       PLATFORM(INTEL_SKYLAKE)
 
 static const struct intel_device_info intel_skylake_gt1_info = {
        SKL_PLATFORM,
@@ -481,7 +495,7 @@ static const struct intel_device_info intel_skylake_gt4_info = {
 };
 
 #define GEN9_LP_FEATURES \
-       .gen = 9, \
+       GEN(9), \
        .is_lp = 1, \
        .has_hotplug = 1, \
        .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \
@@ -513,21 +527,20 @@ static const struct intel_device_info intel_skylake_gt4_info = {
 
 static const struct intel_device_info intel_broxton_info = {
        GEN9_LP_FEATURES,
-       .platform = INTEL_BROXTON,
+       PLATFORM(INTEL_BROXTON),
        .ddb_size = 512,
 };
 
 static const struct intel_device_info intel_geminilake_info = {
        GEN9_LP_FEATURES,
-       .platform = INTEL_GEMINILAKE,
+       PLATFORM(INTEL_GEMINILAKE),
        .ddb_size = 1024,
        GLK_COLORS,
 };
 
 #define KBL_PLATFORM \
        GEN9_FEATURES, \
-       .gen = 9, \
-       .platform = INTEL_KABYLAKE
+       PLATFORM(INTEL_KABYLAKE)
 
 static const struct intel_device_info intel_kabylake_gt1_info = {
        KBL_PLATFORM,
@@ -547,8 +560,7 @@ static const struct intel_device_info intel_kabylake_gt3_info = {
 
 #define CFL_PLATFORM \
        GEN9_FEATURES, \
-       .gen = 9, \
-       .platform = INTEL_COFFEELAKE
+       PLATFORM(INTEL_COFFEELAKE)
 
 static const struct intel_device_info intel_coffeelake_gt1_info = {
        CFL_PLATFORM,
@@ -568,30 +580,32 @@ static const struct intel_device_info intel_coffeelake_gt3_info = {
 
 #define GEN10_FEATURES \
        GEN9_FEATURES, \
+       GEN(10), \
        .ddb_size = 1024, \
        GLK_COLORS
 
 static const struct intel_device_info intel_cannonlake_info = {
        GEN10_FEATURES,
-       .is_alpha_support = 1,
-       .platform = INTEL_CANNONLAKE,
-       .gen = 10,
+       PLATFORM(INTEL_CANNONLAKE),
        .gt = 2,
 };
 
 #define GEN11_FEATURES \
        GEN10_FEATURES, \
-       .gen = 11, \
+       GEN(11), \
        .ddb_size = 2048, \
        .has_csr = 0
 
 static const struct intel_device_info intel_icelake_11_info = {
        GEN11_FEATURES,
-       .platform = INTEL_ICELAKE,
+       PLATFORM(INTEL_ICELAKE),
        .is_alpha_support = 1,
        .has_resource_streamer = 0,
 };
 
+#undef GEN
+#undef PLATFORM
+
 /*
  * Make sure any device matches here are from most specific to most
  * general.  For example, since the Quanta match is based on the subsystem
index 1c440460255ddcd0ff3916107b705fc881d254d6..964467b03e4da992d74e1b68b03f6545d6b9bd48 100644 (file)
@@ -415,7 +415,94 @@ static int i915_pmu_event_init(struct perf_event *event)
        return 0;
 }
 
-static u64 __i915_pmu_event_read(struct perf_event *event)
+static u64 __get_rc6(struct drm_i915_private *i915)
+{
+       u64 val;
+
+       val = intel_rc6_residency_ns(i915,
+                                    IS_VALLEYVIEW(i915) ?
+                                    VLV_GT_RENDER_RC6 :
+                                    GEN6_GT_GFX_RC6);
+
+       if (HAS_RC6p(i915))
+               val += intel_rc6_residency_ns(i915, GEN6_GT_GFX_RC6p);
+
+       if (HAS_RC6pp(i915))
+               val += intel_rc6_residency_ns(i915, GEN6_GT_GFX_RC6pp);
+
+       return val;
+}
+
+static u64 get_rc6(struct drm_i915_private *i915, bool locked)
+{
+#if IS_ENABLED(CONFIG_PM)
+       unsigned long flags;
+       u64 val;
+
+       if (intel_runtime_pm_get_if_in_use(i915)) {
+               val = __get_rc6(i915);
+               intel_runtime_pm_put(i915);
+
+               /*
+                * If we are coming back from being runtime suspended we must
+                * be careful not to report a larger value than returned
+                * previously.
+                */
+
+               if (!locked)
+                       spin_lock_irqsave(&i915->pmu.lock, flags);
+
+               if (val >= i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) {
+                       i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = 0;
+                       i915->pmu.sample[__I915_SAMPLE_RC6].cur = val;
+               } else {
+                       val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur;
+               }
+
+               if (!locked)
+                       spin_unlock_irqrestore(&i915->pmu.lock, flags);
+       } else {
+               struct pci_dev *pdev = i915->drm.pdev;
+               struct device *kdev = &pdev->dev;
+               unsigned long flags2;
+
+               /*
+                * We are runtime suspended.
+                *
+                * Report the delta from when the device was suspended to now,
+                * on top of the last known real value, as the approximated RC6
+                * counter value.
+                */
+               if (!locked)
+                       spin_lock_irqsave(&i915->pmu.lock, flags);
+
+               spin_lock_irqsave(&kdev->power.lock, flags2);
+
+               if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
+                       i915->pmu.suspended_jiffies_last =
+                                               kdev->power.suspended_jiffies;
+
+               val = kdev->power.suspended_jiffies -
+                     i915->pmu.suspended_jiffies_last;
+               val += jiffies - kdev->power.accounting_timestamp;
+
+               spin_unlock_irqrestore(&kdev->power.lock, flags2);
+
+               val = jiffies_to_nsecs(val);
+               val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
+               i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
+
+               if (!locked)
+                       spin_unlock_irqrestore(&i915->pmu.lock, flags);
+       }
+
+       return val;
+#else
+       return __get_rc6(i915);
+#endif
+}
+
+static u64 __i915_pmu_event_read(struct perf_event *event, bool locked)
 {
        struct drm_i915_private *i915 =
                container_of(event->pmu, typeof(*i915), pmu.base);
@@ -453,18 +540,7 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
                        val = count_interrupts(i915);
                        break;
                case I915_PMU_RC6_RESIDENCY:
-                       intel_runtime_pm_get(i915);
-                       val = intel_rc6_residency_ns(i915,
-                                                    IS_VALLEYVIEW(i915) ?
-                                                    VLV_GT_RENDER_RC6 :
-                                                    GEN6_GT_GFX_RC6);
-                       if (HAS_RC6p(i915))
-                               val += intel_rc6_residency_ns(i915,
-                                                             GEN6_GT_GFX_RC6p);
-                       if (HAS_RC6pp(i915))
-                               val += intel_rc6_residency_ns(i915,
-                                                             GEN6_GT_GFX_RC6pp);
-                       intel_runtime_pm_put(i915);
+                       val = get_rc6(i915, locked);
                        break;
                }
        }
@@ -479,7 +555,7 @@ static void i915_pmu_event_read(struct perf_event *event)
 
 again:
        prev = local64_read(&hwc->prev_count);
-       new = __i915_pmu_event_read(event);
+       new = __i915_pmu_event_read(event, false);
 
        if (local64_cmpxchg(&hwc->prev_count, prev, new) != prev)
                goto again;
@@ -534,7 +610,7 @@ static void i915_pmu_enable(struct perf_event *event)
         * for all listeners. Even when the event was already enabled and has
         * an existing non-zero value.
         */
-       local64_set(&event->hw.prev_count, __i915_pmu_event_read(event));
+       local64_set(&event->hw.prev_count, __i915_pmu_event_read(event, true));
 
        spin_unlock_irqrestore(&i915->pmu.lock, flags);
 }
index 5a2e013a56bb6eb52f779c1f51a496cba2cec7e4..aa1b1a987ea1b8a943e8e190d90d01d76e574287 100644 (file)
@@ -27,6 +27,8 @@
 enum {
        __I915_SAMPLE_FREQ_ACT = 0,
        __I915_SAMPLE_FREQ_REQ,
+       __I915_SAMPLE_RC6,
+       __I915_SAMPLE_RC6_ESTIMATED,
        __I915_NUM_PMU_SAMPLERS
 };
 
@@ -94,6 +96,10 @@ struct i915_pmu {
         * struct intel_engine_cs.
         */
        struct i915_pmu_sample sample[__I915_NUM_PMU_SAMPLERS];
+       /**
+        * @suspended_jiffies_last: Cached suspend time from PM core.
+        */
+       unsigned long suspended_jiffies_last;
        /**
         * @i915_attr: Memory block holding device attributes.
         */
index e9c79b5608237c226ee979338343ecdd9d175115..1412abcb27d422e9f34d609d6affc468ea74019b 100644 (file)
@@ -1906,6 +1906,11 @@ enum i915_power_well_id {
 #define   CL_POWER_DOWN_ENABLE         (1 << 4)
 #define   SUS_CLOCK_CONFIG             (3 << 0)
 
+#define _ICL_PORT_CL_DW5_A     0x162014
+#define _ICL_PORT_CL_DW5_B     0x6C014
+#define ICL_PORT_CL_DW5(port)  _MMIO_PORT(port, _ICL_PORT_CL_DW5_A, \
+                                                _ICL_PORT_CL_DW5_B)
+
 #define _PORT_CL1CM_DW9_A              0x162024
 #define _PORT_CL1CM_DW9_BC             0x6C024
 #define   IREF0RC_OFFSET_SHIFT         8
@@ -2029,7 +2034,7 @@ enum i915_power_well_id {
 #define _CNL_PORT_TX_DW5_LN0_AE                0x162454
 #define _CNL_PORT_TX_DW5_LN0_B         0x162654
 #define _CNL_PORT_TX_DW5_LN0_C         0x162C54
-#define _CNL_PORT_TX_DW5_LN0_D         0x162ED4
+#define _CNL_PORT_TX_DW5_LN0_D         0x162E54
 #define _CNL_PORT_TX_DW5_LN0_F         0x162854
 #define CNL_PORT_TX_DW5_GRP(port)      _MMIO_PORT6(port, \
                                                    _CNL_PORT_TX_DW5_GRP_AE, \
@@ -2060,7 +2065,7 @@ enum i915_power_well_id {
 #define _CNL_PORT_TX_DW7_LN0_AE                0x16245C
 #define _CNL_PORT_TX_DW7_LN0_B         0x16265C
 #define _CNL_PORT_TX_DW7_LN0_C         0x162C5C
-#define _CNL_PORT_TX_DW7_LN0_D         0x162EDC
+#define _CNL_PORT_TX_DW7_LN0_D         0x162E5C
 #define _CNL_PORT_TX_DW7_LN0_F         0x16285C
 #define CNL_PORT_TX_DW7_GRP(port)      _MMIO_PORT6(port, \
                                                    _CNL_PORT_TX_DW7_GRP_AE, \
@@ -2104,6 +2109,28 @@ enum i915_power_well_id {
 #define CNL_PORT_COMP_DW9              _MMIO(0x162124)
 #define CNL_PORT_COMP_DW10             _MMIO(0x162128)
 
+#define _ICL_PORT_COMP_DW0_A           0x162100
+#define _ICL_PORT_COMP_DW0_B           0x6C100
+#define ICL_PORT_COMP_DW0(port)                _MMIO_PORT(port, _ICL_PORT_COMP_DW0_A, \
+                                                        _ICL_PORT_COMP_DW0_B)
+#define _ICL_PORT_COMP_DW1_A           0x162104
+#define _ICL_PORT_COMP_DW1_B           0x6C104
+#define ICL_PORT_COMP_DW1(port)                _MMIO_PORT(port, _ICL_PORT_COMP_DW1_A, \
+                                                        _ICL_PORT_COMP_DW1_B)
+#define _ICL_PORT_COMP_DW3_A           0x16210C
+#define _ICL_PORT_COMP_DW3_B           0x6C10C
+#define ICL_PORT_COMP_DW3(port)                _MMIO_PORT(port, _ICL_PORT_COMP_DW3_A, \
+                                                        _ICL_PORT_COMP_DW3_B)
+#define _ICL_PORT_COMP_DW9_A           0x162124
+#define _ICL_PORT_COMP_DW9_B           0x6C124
+#define ICL_PORT_COMP_DW9(port)                _MMIO_PORT(port, _ICL_PORT_COMP_DW9_A, \
+                                                        _ICL_PORT_COMP_DW9_B)
+#define _ICL_PORT_COMP_DW10_A          0x162128
+#define _ICL_PORT_COMP_DW10_B          0x6C128
+#define ICL_PORT_COMP_DW10(port)       _MMIO_PORT(port, \
+                                                  _ICL_PORT_COMP_DW10_A, \
+                                                  _ICL_PORT_COMP_DW10_B)
+
 /* BXT PHY Ref registers */
 #define _PORT_REF_DW3_A                        0x16218C
 #define _PORT_REF_DW3_BC               0x6C18C
@@ -7138,6 +7165,8 @@ enum {
 #define  DISP_DATA_PARTITION_5_6       (1<<6)
 #define  DISP_IPC_ENABLE               (1<<3)
 #define DBUF_CTL       _MMIO(0x45008)
+#define DBUF_CTL_S1    _MMIO(0x45008)
+#define DBUF_CTL_S2    _MMIO(0x44FE8)
 #define  DBUF_POWER_REQUEST            (1<<31)
 #define  DBUF_POWER_STATE              (1<<30)
 #define GEN7_MSG_CTL   _MMIO(0x45010)
@@ -7147,8 +7176,9 @@ enum {
 #define  RESET_PCH_HANDSHAKE_ENABLE    (1<<4)
 
 #define GEN8_CHICKEN_DCPR_1            _MMIO(0x46430)
-#define   SKL_SELECT_ALTERNATE_DC_EXIT (1<<30)
-#define   MASK_WAKEMEM                 (1<<13)
+#define   SKL_SELECT_ALTERNATE_DC_EXIT (1 << 30)
+#define   MASK_WAKEMEM                 (1 << 13)
+#define   CNL_DDI_CLOCK_REG_ACCESS_ON  (1 << 7)
 
 #define SKL_DFSM                       _MMIO(0x51000)
 #define SKL_DFSM_CDCLK_LIMIT_MASK      (3 << 23)
@@ -7160,8 +7190,12 @@ enum {
 #define SKL_DFSM_PIPE_B_DISABLE                (1 << 21)
 #define SKL_DFSM_PIPE_C_DISABLE                (1 << 28)
 
-#define SKL_DSSM                       _MMIO(0x51004)
-#define CNL_DSSM_CDCLK_PLL_REFCLK_24MHz        (1 << 31)
+#define SKL_DSSM                               _MMIO(0x51004)
+#define CNL_DSSM_CDCLK_PLL_REFCLK_24MHz                (1 << 31)
+#define ICL_DSSM_CDCLK_PLL_REFCLK_MASK         (7 << 29)
+#define ICL_DSSM_CDCLK_PLL_REFCLK_24MHz                (0 << 29)
+#define ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz      (1 << 29)
+#define ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz      (2 << 29)
 
 #define GEN7_FF_SLICE_CS_CHICKEN1      _MMIO(0x20e0)
 #define   GEN9_FFSC_PERCTX_PREEMPT_CTRL        (1<<14)
@@ -8794,20 +8828,21 @@ enum skl_power_gate {
 
 /* CDCLK_CTL */
 #define CDCLK_CTL                      _MMIO(0x46000)
-#define  CDCLK_FREQ_SEL_MASK           (3<<26)
-#define  CDCLK_FREQ_450_432            (0<<26)
-#define  CDCLK_FREQ_540                        (1<<26)
-#define  CDCLK_FREQ_337_308            (2<<26)
-#define  CDCLK_FREQ_675_617            (3<<26)
-#define  BXT_CDCLK_CD2X_DIV_SEL_MASK   (3<<22)
-#define  BXT_CDCLK_CD2X_DIV_SEL_1      (0<<22)
-#define  BXT_CDCLK_CD2X_DIV_SEL_1_5    (1<<22)
-#define  BXT_CDCLK_CD2X_DIV_SEL_2      (2<<22)
-#define  BXT_CDCLK_CD2X_DIV_SEL_4      (3<<22)
-#define  BXT_CDCLK_CD2X_PIPE(pipe)     ((pipe)<<20)
-#define  CDCLK_DIVMUX_CD_OVERRIDE      (1<<19)
+#define  CDCLK_FREQ_SEL_MASK           (3 << 26)
+#define  CDCLK_FREQ_450_432            (0 << 26)
+#define  CDCLK_FREQ_540                        (1 << 26)
+#define  CDCLK_FREQ_337_308            (2 << 26)
+#define  CDCLK_FREQ_675_617            (3 << 26)
+#define  BXT_CDCLK_CD2X_DIV_SEL_MASK   (3 << 22)
+#define  BXT_CDCLK_CD2X_DIV_SEL_1      (0 << 22)
+#define  BXT_CDCLK_CD2X_DIV_SEL_1_5    (1 << 22)
+#define  BXT_CDCLK_CD2X_DIV_SEL_2      (2 << 22)
+#define  BXT_CDCLK_CD2X_DIV_SEL_4      (3 << 22)
+#define  BXT_CDCLK_CD2X_PIPE(pipe)     ((pipe) << 20)
+#define  CDCLK_DIVMUX_CD_OVERRIDE      (1 << 19)
 #define  BXT_CDCLK_CD2X_PIPE_NONE      BXT_CDCLK_CD2X_PIPE(3)
-#define  BXT_CDCLK_SSA_PRECHARGE_ENABLE        (1<<16)
+#define  ICL_CDCLK_CD2X_PIPE_NONE      (7 << 19)
+#define  BXT_CDCLK_SSA_PRECHARGE_ENABLE        (1 << 16)
 #define  CDCLK_FREQ_DECIMAL_MASK       (0x7ff)
 
 /* LCPLL_CTL */
@@ -9716,4 +9751,10 @@ enum skl_power_gate {
 #define  MMCD_PCLA             (1 << 31)
 #define  MMCD_HOTSPOT_EN       (1 << 27)
 
+#define _ICL_PHY_MISC_A                0x64C00
+#define _ICL_PHY_MISC_B                0x64C04
+#define ICL_PHY_MISC(port)     _MMIO_PORT(port, _ICL_PHY_MISC_A, \
+                                                _ICL_PHY_MISC_B)
+#define  ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN      (1 << 23)
+
 #endif /* _I915_REG_H_ */
index 0087acf731a851a2d87a112092a0d76f032a8088..58f8d0cc125c0e6e58a30973d8443037208f4bb4 100644 (file)
@@ -86,7 +86,7 @@ struct i915_syncmap {
 
 /**
  * i915_syncmap_init -- initialise the #i915_syncmap
- * @root - pointer to the #i915_syncmap
+ * @root: pointer to the #i915_syncmap
  */
 void i915_syncmap_init(struct i915_syncmap **root)
 {
@@ -139,9 +139,9 @@ static inline bool seqno_later(u32 a, u32 b)
 
 /**
  * i915_syncmap_is_later -- compare against the last know sync point
- * @root - pointer to the #i915_syncmap
- * @id - the context id (other timeline) we are synchronising to
- * @seqno - the sequence number along the other timeline
+ * @root: pointer to the #i915_syncmap
+ * @id: the context id (other timeline) we are synchronising to
+ * @seqno: the sequence number along the other timeline
  *
  * If we have already synchronised this @root timeline with another (@id) then
  * we can omit any repeated or earlier synchronisation requests. If the two
@@ -339,9 +339,9 @@ found:
 
 /**
  * i915_syncmap_set -- mark the most recent syncpoint between contexts
- * @root - pointer to the #i915_syncmap
- * @id - the context id (other timeline) we have synchronised to
- * @seqno - the sequence number along the other timeline
+ * @root: pointer to the #i915_syncmap
+ * @id: the context id (other timeline) we have synchronised to
+ * @seqno: the sequence number along the other timeline
  *
  * When we synchronise this @root timeline with another (@id), we also know
  * that we have synchronized with all previous seqno along that timeline. If
@@ -382,7 +382,7 @@ static void __sync_free(struct i915_syncmap *p)
 
 /**
  * i915_syncmap_free -- free all memory associated with the syncmap
- * @root - pointer to the #i915_syncmap
+ * @root: pointer to the #i915_syncmap
  *
  * Either when the timeline is to be freed and we no longer need the sync
  * point tracking, or when the fences are all known to be signaled and the
index d452c327dc1daf3a3d3dddea0e38491a2173ae17..e9fb692076d75b86109ec57dfb7590b94a4b1562 100644 (file)
@@ -188,13 +188,14 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 /**
  * intel_crtc_destroy_state - destroy crtc state
  * @crtc: drm crtc
+ * @state: the state to destroy
  *
  * Destroys the crtc state (both common and Intel-specific) for the
  * specified crtc.
  */
 void
 intel_crtc_destroy_state(struct drm_crtc *crtc,
-                         struct drm_crtc_state *state)
+                        struct drm_crtc_state *state)
 {
        drm_atomic_helper_crtc_destroy_state(crtc, state);
 }
@@ -202,7 +203,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
 /**
  * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests
  * @dev_priv: i915 device
- * @crtc: intel crtc
+ * @intel_crtc: intel crtc
  * @crtc_state: incoming crtc_state to validate and setup scalers
  *
  * This function sets up scalers based on staged scaling requests for
index 0ee32275994a2eb6b89a7d5082c407939669333f..7481ce85746b4f24fdbb870f33276879417cbebc 100644 (file)
@@ -85,6 +85,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
        __drm_atomic_helper_plane_duplicate_state(plane, state);
 
        intel_state->vma = NULL;
+       intel_state->flags = 0;
 
        return state;
 }
index 522d54fecb53489193eb2b72dbf9fdd41009ac67..709d6ca680747d8d4458c72945093a8052d6f8c4 100644 (file)
@@ -704,7 +704,7 @@ void intel_init_audio_hooks(struct drm_i915_private *dev_priv)
        } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                dev_priv->display.audio_codec_enable = ilk_audio_codec_enable;
                dev_priv->display.audio_codec_disable = ilk_audio_codec_disable;
-       } else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8) {
+       } else if (IS_HASWELL(dev_priv) || INTEL_GEN(dev_priv) >= 8) {
                dev_priv->display.audio_codec_enable = hsw_audio_codec_enable;
                dev_priv->display.audio_codec_disable = hsw_audio_codec_disable;
        } else if (HAS_PCH_SPLIT(dev_priv)) {
@@ -779,11 +779,11 @@ static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv,
 {
        struct intel_encoder *encoder;
 
-       if (WARN_ON(pipe >= ARRAY_SIZE(dev_priv->av_enc_map)))
-               return NULL;
-
        /* MST */
        if (pipe >= 0) {
+               if (WARN_ON(pipe >= ARRAY_SIZE(dev_priv->av_enc_map)))
+                       return NULL;
+
                encoder = dev_priv->av_enc_map[pipe];
                /*
                 * when bootup, audio driver may not know it is
index 4e74aa2f16bc0d96d36dddbe76804335a3875d91..c5c7530ba1570618d06a04f789029944296366de 100644 (file)
@@ -391,7 +391,7 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv,
 static int intel_bios_ssc_frequency(struct drm_i915_private *dev_priv,
                                    bool alternate)
 {
-       switch (INTEL_INFO(dev_priv)->gen) {
+       switch (INTEL_GEN(dev_priv)) {
        case 2:
                return alternate ? 66667 : 48000;
        case 3:
@@ -947,6 +947,86 @@ static int goto_next_sequence_v3(const u8 *data, int index, int total)
        return 0;
 }
 
+/*
+ * Get len of pre-fixed deassert fragment from a v1 init OTP sequence,
+ * skip all delay + gpio operands and stop at the first DSI packet op.
+ */
+static int get_init_otp_deassert_fragment_len(struct drm_i915_private *dev_priv)
+{
+       const u8 *data = dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP];
+       int index, len;
+
+       if (WARN_ON(!data || dev_priv->vbt.dsi.seq_version != 1))
+               return 0;
+
+       /* index = 1 to skip sequence byte */
+       for (index = 1; data[index] != MIPI_SEQ_ELEM_END; index += len) {
+               switch (data[index]) {
+               case MIPI_SEQ_ELEM_SEND_PKT:
+                       return index == 1 ? 0 : index;
+               case MIPI_SEQ_ELEM_DELAY:
+                       len = 5; /* 1 byte for operand + uint32 */
+                       break;
+               case MIPI_SEQ_ELEM_GPIO:
+                       len = 3; /* 1 byte for op, 1 for gpio_nr, 1 for value */
+                       break;
+               default:
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Some v1 VBT MIPI sequences do the deassert in the init OTP sequence.
+ * The deassert must be done before calling intel_dsi_device_ready, so for
+ * these devices we split the init OTP sequence into a deassert sequence and
+ * the actual init OTP part.
+ */
+static void fixup_mipi_sequences(struct drm_i915_private *dev_priv)
+{
+       u8 *init_otp;
+       int len;
+
+       /* Limit this to VLV for now. */
+       if (!IS_VALLEYVIEW(dev_priv))
+               return;
+
+       /* Limit this to v1 vid-mode sequences */
+       if (dev_priv->vbt.dsi.config->is_cmd_mode ||
+           dev_priv->vbt.dsi.seq_version != 1)
+               return;
+
+       /* Only do this if there are otp and assert seqs and no deassert seq */
+       if (!dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] ||
+           !dev_priv->vbt.dsi.sequence[MIPI_SEQ_ASSERT_RESET] ||
+           dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET])
+               return;
+
+       /* The deassert-sequence ends at the first DSI packet */
+       len = get_init_otp_deassert_fragment_len(dev_priv);
+       if (!len)
+               return;
+
+       DRM_DEBUG_KMS("Using init OTP fragment to deassert reset\n");
+
+       /* Copy the fragment, update seq byte and terminate it */
+       init_otp = (u8 *)dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP];
+       dev_priv->vbt.dsi.deassert_seq = kmemdup(init_otp, len + 1, GFP_KERNEL);
+       if (!dev_priv->vbt.dsi.deassert_seq)
+               return;
+       dev_priv->vbt.dsi.deassert_seq[0] = MIPI_SEQ_DEASSERT_RESET;
+       dev_priv->vbt.dsi.deassert_seq[len] = MIPI_SEQ_ELEM_END;
+       /* Use the copy for deassert */
+       dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET] =
+               dev_priv->vbt.dsi.deassert_seq;
+       /* Replace the last byte of the fragment with init OTP seq byte */
+       init_otp[len - 1] = MIPI_SEQ_INIT_OTP;
+       /* And make MIPI_MIPI_SEQ_INIT_OTP point to it */
+       dev_priv->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] = init_otp + len - 1;
+}
+
 static void
 parse_mipi_sequence(struct drm_i915_private *dev_priv,
                    const struct bdb_header *bdb)
@@ -1016,6 +1096,8 @@ parse_mipi_sequence(struct drm_i915_private *dev_priv,
        dev_priv->vbt.dsi.size = seq_size;
        dev_priv->vbt.dsi.seq_version = sequence->version;
 
+       fixup_mipi_sequences(dev_priv);
+
        DRM_DEBUG_DRIVER("MIPI related VBT parsing complete\n");
        return;
 
@@ -1610,6 +1692,29 @@ out:
                pci_unmap_rom(pdev, bios);
 }
 
+/**
+ * intel_bios_cleanup - Free any resources allocated by intel_bios_init()
+ * @dev_priv: i915 device instance
+ */
+void intel_bios_cleanup(struct drm_i915_private *dev_priv)
+{
+       kfree(dev_priv->vbt.child_dev);
+       dev_priv->vbt.child_dev = NULL;
+       dev_priv->vbt.child_dev_num = 0;
+       kfree(dev_priv->vbt.sdvo_lvds_vbt_mode);
+       dev_priv->vbt.sdvo_lvds_vbt_mode = NULL;
+       kfree(dev_priv->vbt.lfp_lvds_vbt_mode);
+       dev_priv->vbt.lfp_lvds_vbt_mode = NULL;
+       kfree(dev_priv->vbt.dsi.data);
+       dev_priv->vbt.dsi.data = NULL;
+       kfree(dev_priv->vbt.dsi.pps);
+       dev_priv->vbt.dsi.pps = NULL;
+       kfree(dev_priv->vbt.dsi.config);
+       dev_priv->vbt.dsi.config = NULL;
+       kfree(dev_priv->vbt.dsi.deassert_seq);
+       dev_priv->vbt.dsi.deassert_seq = NULL;
+}
+
 /**
  * intel_bios_is_tv_present - is integrated TV present in VBT
  * @dev_priv:  i915 device instance
index efbc627a2a2563adc3ed9e6023de1a0d0ecc408c..b955f7d7bd0f866f4b071324379333240b764997 100644 (file)
@@ -588,29 +588,16 @@ void intel_engine_remove_wait(struct intel_engine_cs *engine,
        spin_unlock_irq(&b->rb_lock);
 }
 
-static bool signal_valid(const struct drm_i915_gem_request *request)
-{
-       return intel_wait_check_request(&request->signaling.wait, request);
-}
-
 static bool signal_complete(const struct drm_i915_gem_request *request)
 {
        if (!request)
                return false;
 
-       /* If another process served as the bottom-half it may have already
-        * signalled that this wait is already completed.
-        */
-       if (intel_wait_complete(&request->signaling.wait))
-               return signal_valid(request);
-
-       /* Carefully check if the request is complete, giving time for the
+       /*
+        * Carefully check if the request is complete, giving time for the
         * seqno to be visible or if the GPU hung.
         */
-       if (__i915_request_irq_complete(request))
-               return true;
-
-       return false;
+       return __i915_request_irq_complete(request);
 }
 
 static struct drm_i915_gem_request *to_signaler(struct rb_node *rb)
@@ -712,6 +699,7 @@ static int intel_breadcrumbs_signaler(void *arg)
                                      &request->fence.flags)) {
                                local_bh_disable();
                                dma_fence_signal(&request->fence);
+                               GEM_BUG_ON(!i915_gem_request_completed(request));
                                local_bh_enable(); /* kick start the tasklets */
                        }
 
index ee788d5be5e36b22bf4af1c9787410315c0fb94f..dc7db8a2caf8a397456ae520ad5d3da43dccf47e 100644 (file)
@@ -1778,6 +1778,199 @@ sanitize:
        dev_priv->cdclk.hw.vco = -1;
 }
 
+static int icl_calc_cdclk(int min_cdclk, unsigned int ref)
+{
+       int ranges_24[] = { 312000, 552000, 648000 };
+       int ranges_19_38[] = { 307200, 556800, 652800 };
+       int *ranges;
+
+       switch (ref) {
+       default:
+               MISSING_CASE(ref);
+       case 24000:
+               ranges = ranges_24;
+               break;
+       case 19200:
+       case 38400:
+               ranges = ranges_19_38;
+               break;
+       }
+
+       if (min_cdclk > ranges[1])
+               return ranges[2];
+       else if (min_cdclk > ranges[0])
+               return ranges[1];
+       else
+               return ranges[0];
+}
+
+static int icl_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
+{
+       int ratio;
+
+       if (cdclk == dev_priv->cdclk.hw.bypass)
+               return 0;
+
+       switch (cdclk) {
+       default:
+               MISSING_CASE(cdclk);
+       case 307200:
+       case 556800:
+       case 652800:
+               WARN_ON(dev_priv->cdclk.hw.ref != 19200 &&
+                       dev_priv->cdclk.hw.ref != 38400);
+               break;
+       case 312000:
+       case 552000:
+       case 648000:
+               WARN_ON(dev_priv->cdclk.hw.ref != 24000);
+       }
+
+       ratio = cdclk / (dev_priv->cdclk.hw.ref / 2);
+
+       return dev_priv->cdclk.hw.ref * ratio;
+}
+
+static void icl_set_cdclk(struct drm_i915_private *dev_priv,
+                         const struct intel_cdclk_state *cdclk_state)
+{
+       unsigned int cdclk = cdclk_state->cdclk;
+       unsigned int vco = cdclk_state->vco;
+       int ret;
+
+       mutex_lock(&dev_priv->pcu_lock);
+       ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
+                               SKL_CDCLK_PREPARE_FOR_CHANGE,
+                               SKL_CDCLK_READY_FOR_CHANGE,
+                               SKL_CDCLK_READY_FOR_CHANGE, 3);
+       mutex_unlock(&dev_priv->pcu_lock);
+       if (ret) {
+               DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
+                         ret);
+               return;
+       }
+
+       if (dev_priv->cdclk.hw.vco != 0 &&
+           dev_priv->cdclk.hw.vco != vco)
+               cnl_cdclk_pll_disable(dev_priv);
+
+       if (dev_priv->cdclk.hw.vco != vco)
+               cnl_cdclk_pll_enable(dev_priv, vco);
+
+       I915_WRITE(CDCLK_CTL, ICL_CDCLK_CD2X_PIPE_NONE |
+                             skl_cdclk_decimal(cdclk));
+
+       mutex_lock(&dev_priv->pcu_lock);
+       /* TODO: add proper DVFS support. */
+       sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, 2);
+       mutex_unlock(&dev_priv->pcu_lock);
+
+       intel_update_cdclk(dev_priv);
+}
+
+static void icl_get_cdclk(struct drm_i915_private *dev_priv,
+                         struct intel_cdclk_state *cdclk_state)
+{
+       u32 val;
+
+       cdclk_state->bypass = 50000;
+
+       val = I915_READ(SKL_DSSM);
+       switch (val & ICL_DSSM_CDCLK_PLL_REFCLK_MASK) {
+       default:
+               MISSING_CASE(val);
+       case ICL_DSSM_CDCLK_PLL_REFCLK_24MHz:
+               cdclk_state->ref = 24000;
+               break;
+       case ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz:
+               cdclk_state->ref = 19200;
+               break;
+       case ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz:
+               cdclk_state->ref = 38400;
+               break;
+       }
+
+       val = I915_READ(BXT_DE_PLL_ENABLE);
+       if ((val & BXT_DE_PLL_PLL_ENABLE) == 0 ||
+           (val & BXT_DE_PLL_LOCK) == 0) {
+               /*
+                * CDCLK PLL is disabled, the VCO/ratio doesn't matter, but
+                * setting it to zero is a way to signal that.
+                */
+               cdclk_state->vco = 0;
+               cdclk_state->cdclk = cdclk_state->bypass;
+               return;
+       }
+
+       cdclk_state->vco = (val & BXT_DE_PLL_RATIO_MASK) * cdclk_state->ref;
+
+       val = I915_READ(CDCLK_CTL);
+       WARN_ON((val & BXT_CDCLK_CD2X_DIV_SEL_MASK) != 0);
+
+       cdclk_state->cdclk = cdclk_state->vco / 2;
+}
+
+/**
+ * icl_init_cdclk - Initialize CDCLK on ICL
+ * @dev_priv: i915 device
+ *
+ * Initialize CDCLK for ICL. This consists mainly of initializing
+ * dev_priv->cdclk.hw and sanitizing the state of the hardware if needed. This
+ * is generally done only during the display core initialization sequence, after
+ * which the DMC will take care of turning CDCLK off/on as needed.
+ */
+void icl_init_cdclk(struct drm_i915_private *dev_priv)
+{
+       struct intel_cdclk_state sanitized_state;
+       u32 val;
+
+       /* This sets dev_priv->cdclk.hw. */
+       intel_update_cdclk(dev_priv);
+       intel_dump_cdclk_state(&dev_priv->cdclk.hw, "Current CDCLK");
+
+       /* This means CDCLK disabled. */
+       if (dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
+               goto sanitize;
+
+       val = I915_READ(CDCLK_CTL);
+
+       if ((val & BXT_CDCLK_CD2X_DIV_SEL_MASK) != 0)
+               goto sanitize;
+
+       if ((val & CDCLK_FREQ_DECIMAL_MASK) !=
+           skl_cdclk_decimal(dev_priv->cdclk.hw.cdclk))
+               goto sanitize;
+
+       return;
+
+sanitize:
+       DRM_DEBUG_KMS("Sanitizing cdclk programmed by pre-os\n");
+
+       sanitized_state.ref = dev_priv->cdclk.hw.ref;
+       sanitized_state.cdclk = icl_calc_cdclk(0, sanitized_state.ref);
+       sanitized_state.vco = icl_calc_cdclk_pll_vco(dev_priv,
+                                                    sanitized_state.cdclk);
+
+       icl_set_cdclk(dev_priv, &sanitized_state);
+}
+
+/**
+ * icl_uninit_cdclk - Uninitialize CDCLK on ICL
+ * @dev_priv: i915 device
+ *
+ * Uninitialize CDCLK for ICL. This is done only during the display core
+ * uninitialization sequence.
+ */
+void icl_uninit_cdclk(struct drm_i915_private *dev_priv)
+{
+       struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw;
+
+       cdclk_state.cdclk = cdclk_state.bypass;
+       cdclk_state.vco = 0;
+
+       icl_set_cdclk(dev_priv, &cdclk_state);
+}
+
 /**
  * cnl_init_cdclk - Initialize CDCLK on CNL
  * @dev_priv: i915 device
@@ -2216,6 +2409,36 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
        return 0;
 }
 
+static int icl_modeset_calc_cdclk(struct drm_atomic_state *state)
+{
+       struct drm_i915_private *dev_priv = to_i915(state->dev);
+       struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
+       unsigned int ref = intel_state->cdclk.logical.ref;
+       int min_cdclk, cdclk, vco;
+
+       min_cdclk = intel_compute_min_cdclk(state);
+       if (min_cdclk < 0)
+               return min_cdclk;
+
+       cdclk = icl_calc_cdclk(min_cdclk, ref);
+       vco = icl_calc_cdclk_pll_vco(dev_priv, cdclk);
+
+       intel_state->cdclk.logical.vco = vco;
+       intel_state->cdclk.logical.cdclk = cdclk;
+
+       if (!intel_state->active_crtcs) {
+               cdclk = icl_calc_cdclk(0, ref);
+               vco = icl_calc_cdclk_pll_vco(dev_priv, cdclk);
+
+               intel_state->cdclk.actual.vco = vco;
+               intel_state->cdclk.actual.cdclk = cdclk;
+       } else {
+               intel_state->cdclk.actual = intel_state->cdclk.logical;
+       }
+
+       return 0;
+}
+
 static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
 {
        int max_cdclk_freq = dev_priv->max_cdclk_freq;
@@ -2233,7 +2456,7 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
                return max_cdclk_freq;
        else if (IS_CHERRYVIEW(dev_priv))
                return max_cdclk_freq*95/100;
-       else if (INTEL_INFO(dev_priv)->gen < 4)
+       else if (INTEL_GEN(dev_priv) < 4)
                return 2*max_cdclk_freq*90/100;
        else
                return max_cdclk_freq*90/100;
@@ -2249,7 +2472,12 @@ static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
  */
 void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
 {
-       if (IS_CANNONLAKE(dev_priv)) {
+       if (IS_ICELAKE(dev_priv)) {
+               if (dev_priv->cdclk.hw.ref == 24000)
+                       dev_priv->max_cdclk_freq = 648000;
+               else
+                       dev_priv->max_cdclk_freq = 652800;
+       } else if (IS_CANNONLAKE(dev_priv)) {
                dev_priv->max_cdclk_freq = 528000;
        } else if (IS_GEN9_BC(dev_priv)) {
                u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
@@ -2473,9 +2701,14 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
                dev_priv->display.set_cdclk = cnl_set_cdclk;
                dev_priv->display.modeset_calc_cdclk =
                        cnl_modeset_calc_cdclk;
+       } else if (IS_ICELAKE(dev_priv)) {
+               dev_priv->display.set_cdclk = icl_set_cdclk;
+               dev_priv->display.modeset_calc_cdclk = icl_modeset_calc_cdclk;
        }
 
-       if (IS_CANNONLAKE(dev_priv))
+       if (IS_ICELAKE(dev_priv))
+               dev_priv->display.get_cdclk = icl_get_cdclk;
+       else if (IS_CANNONLAKE(dev_priv))
                dev_priv->display.get_cdclk = cnl_get_cdclk;
        else if (IS_GEN9_BC(dev_priv))
                dev_priv->display.get_cdclk = skl_get_cdclk;
index 1cd4a7c22bd56a37e96f05b648676bb1e05bf2e5..391dd69ae0a491ef980f90c6070beb98532539ae 100644 (file)
@@ -474,14 +474,6 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector)
        return ret;
 }
 
-/**
- * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
- *
- * Not for i915G/i915GM
- *
- * \return true if CRT is connected.
- * \return false if CRT is disconnected.
- */
 static bool intel_crt_detect_hotplug(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
@@ -807,10 +799,11 @@ intel_crt_detect(struct drm_connector *connector,
                else
                        status = connector_status_unknown;
                intel_release_load_detect_pipe(connector, &tmp, ctx);
-       } else if (ret == 0)
+       } else if (ret == 0) {
                status = connector_status_unknown;
-       else if (ret < 0)
+       } else {
                status = ret;
+       }
 
 out:
        intel_display_power_put(dev_priv, intel_encoder->power_domain);
index cfcd9cb37d5d138665e504e691959b84c00811b8..8ca376aca8bd4c884949ada00fa5105d388c13a5 100644 (file)
@@ -2152,7 +2152,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
 
                I915_WRITE(DPLL_CTRL2, val);
 
-       } else if (INTEL_INFO(dev_priv)->gen < 9) {
+       } else if (INTEL_GEN(dev_priv) < 9) {
                I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll));
        }
 
index a2c16140169fcea0ba83b325ab3aa65457512570..298f8996cc540d236ef397a9d8929ee36b967159 100644 (file)
@@ -586,3 +586,9 @@ void intel_device_info_runtime_init(struct intel_device_info *info)
        /* Initialize command stream timestamp frequency */
        info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv);
 }
+
+void intel_driver_caps_print(const struct intel_driver_caps *caps,
+                            struct drm_printer *p)
+{
+       drm_printf(p, "scheduler: %x\n", caps->scheduler);
+}
index 9542018d11d0fbdf7b094620e33d74af50fb9831..71fdfb0451ef8e4a0fb2dd612eb47ca9132c94bf 100644 (file)
@@ -167,6 +167,10 @@ struct intel_device_info {
        } color;
 };
 
+struct intel_driver_caps {
+       unsigned int scheduler;
+};
+
 static inline unsigned int sseu_subslice_total(const struct sseu_dev_info *sseu)
 {
        return hweight8(sseu->slice_mask) * hweight8(sseu->subslice_mask);
@@ -182,4 +186,7 @@ void intel_device_info_dump_flags(const struct intel_device_info *info,
 void intel_device_info_dump_runtime(const struct intel_device_info *info,
                                    struct drm_printer *p);
 
+void intel_driver_caps_print(const struct intel_driver_caps *caps,
+                            struct drm_printer *p);
+
 #endif
index 60ba5bb3f34cfa9ce7fe6351076d58148757e7af..5d46771d58f6b8179d5ffcedf1730f4954711af4 100644 (file)
@@ -558,11 +558,11 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock)
 }
 
 #define INTELPllInvalid(s)   do { /* DRM_DEBUG(s); */ return false; } while (0)
-/**
+
+/*
  * Returns whether the given set of divisors are valid for a given refclk with
  * the given connectors.
  */
-
 static bool intel_PLL_is_valid(struct drm_i915_private *dev_priv,
                               const struct intel_limit *limit,
                               const struct dpll *clock)
@@ -2029,12 +2029,12 @@ static unsigned int intel_cursor_alignment(const struct drm_i915_private *dev_pr
 
 static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_priv)
 {
-       if (INTEL_INFO(dev_priv)->gen >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                return 256 * 1024;
        else if (IS_I965G(dev_priv) || IS_I965GM(dev_priv) ||
                 IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                return 128 * 1024;
-       else if (INTEL_INFO(dev_priv)->gen >= 4)
+       else if (INTEL_GEN(dev_priv) >= 4)
                return 4 * 1024;
        else
                return 0;
@@ -2068,13 +2068,16 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
 }
 
 struct i915_vma *
-intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
+intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
+                          unsigned int rotation,
+                          unsigned long *out_flags)
 {
        struct drm_device *dev = fb->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_i915_gem_object *obj = intel_fb_obj(fb);
        struct i915_ggtt_view view;
        struct i915_vma *vma;
+       unsigned int pinctl;
        u32 alignment;
 
        WARN_ON(!mutex_is_locked(&dev->struct_mutex));
@@ -2102,7 +2105,20 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
 
        atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
 
-       vma = i915_gem_object_pin_to_display_plane(obj, alignment, &view);
+       pinctl = 0;
+
+       /* Valleyview is definitely limited to scanning out the first
+        * 512MiB. Lets presume this behaviour was inherited from the
+        * g4x display engine and that all earlier gen are similarly
+        * limited. Testing suggests that it is a little more
+        * complicated than this. For example, Cherryview appears quite
+        * happy to scanout from anywhere within its global aperture.
+        */
+       if (HAS_GMCH_DISPLAY(dev_priv))
+               pinctl |= PIN_MAPPABLE;
+
+       vma = i915_gem_object_pin_to_display_plane(obj,
+                                                  alignment, &view, pinctl);
        if (IS_ERR(vma))
                goto err;
 
@@ -2123,7 +2139,8 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
                 * something and try to run the system in a "less than optimal"
                 * mode that matches the user configuration.
                 */
-               i915_vma_pin_fence(vma);
+               if (i915_vma_pin_fence(vma) == 0 && vma->fence)
+                       *out_flags |= PLANE_HAS_FENCE;
        }
 
        i915_vma_get(vma);
@@ -2134,11 +2151,12 @@ err:
        return vma;
 }
 
-void intel_unpin_fb_vma(struct i915_vma *vma)
+void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
 {
        lockdep_assert_held(&vma->vm->i915->drm.struct_mutex);
 
-       i915_vma_unpin_fence(vma);
+       if (flags & PLANE_HAS_FENCE)
+               i915_vma_unpin_fence(vma);
        i915_gem_object_unpin_from_display_plane(vma);
        i915_vma_put(vma);
 }
@@ -2808,7 +2826,9 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 valid_fb:
        mutex_lock(&dev->struct_mutex);
        intel_state->vma =
-               intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
+               intel_pin_and_fence_fb_obj(fb,
+                                          primary->state->rotation,
+                                          &intel_state->flags);
        mutex_unlock(&dev->struct_mutex);
        if (IS_ERR(intel_state->vma)) {
                DRM_ERROR("failed to pin boot fb on pipe %d: %li\n",
@@ -3163,7 +3183,7 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
                dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
 
-       if (INTEL_GEN(dev_priv) < 4)
+       if (INTEL_GEN(dev_priv) < 5)
                dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe);
 
        switch (fb->format->format) {
@@ -4756,8 +4776,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
 
 /**
  * skl_update_scaler_plane - Stages update to scaler state for a given plane.
- *
- * @state: crtc's scaler state
+ * @crtc_state: crtc's scaler state
  * @plane_state: atomic plane state to update
  *
  * Return
@@ -4954,6 +4973,7 @@ static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc)
 /**
  * intel_post_enable_primary - Perform operations after enabling primary plane
  * @crtc: the CRTC whose primary plane was just enabled
+ * @new_crtc_state: the enabling state
  *
  * Performs potentially sleeping operations that must be done after the primary
  * plane is enabled, such as updating FBC and IPS.  Note that this may be
@@ -5418,6 +5438,20 @@ static void glk_pipe_scaler_clock_gating_wa(struct drm_i915_private *dev_priv,
        I915_WRITE(CLKGATE_DIS_PSL(pipe), val);
 }
 
+static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
+{
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum pipe pipe = crtc->pipe;
+       uint32_t val;
+
+       val = MBUS_DBOX_BW_CREDIT(1) | MBUS_DBOX_A_CREDIT(2);
+
+       /* Program B credit equally to all pipes */
+       val |= MBUS_DBOX_B_CREDIT(24 / INTEL_INFO(dev_priv)->num_pipes);
+
+       I915_WRITE(PIPE_MBUS_DBOX_CTL(pipe), val);
+}
+
 static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
                                struct drm_atomic_state *old_state)
 {
@@ -5495,6 +5529,9 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
        if (dev_priv->display.initial_watermarks != NULL)
                dev_priv->display.initial_watermarks(old_intel_state, pipe_config);
 
+       if (INTEL_GEN(dev_priv) >= 11)
+               icl_pipe_mbus_enable(intel_crtc);
+
        /* XXX: Do the pipe assertions at the right place for BXT DSI. */
        if (!transcoder_is_dsi(cpu_transcoder))
                intel_enable_pipe(pipe_config);
@@ -6307,7 +6344,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
        const struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
        /* GDG double wide on either pipe, otherwise pipe A only */
-       return INTEL_INFO(dev_priv)->gen < 4 &&
+       return INTEL_GEN(dev_priv) < 4 &&
                (crtc->pipe == PIPE_A || IS_I915G(dev_priv));
 }
 
@@ -8194,7 +8231,7 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_crtc_state *config = intel_crtc->config;
 
-       if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) {
+       if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) {
                u32 val = 0;
 
                switch (intel_crtc->config->pipe_bpp) {
@@ -9537,7 +9574,8 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
        if (HAS_DDI(dev_priv))
                cntl |= CURSOR_PIPE_CSC_ENABLE;
 
-       cntl |= MCURSOR_PIPE_SELECT(crtc->pipe);
+       if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
+               cntl |= MCURSOR_PIPE_SELECT(crtc->pipe);
 
        switch (plane_state->base.crtc_w) {
        case 64:
@@ -10702,6 +10740,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
        struct drm_connector_list_iter conn_iter;
        unsigned int used_ports = 0;
        unsigned int used_mst_ports = 0;
+       bool ret = true;
 
        /*
         * Walk the connector list instead of the encoder
@@ -10736,7 +10775,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
 
                        /* the same port mustn't appear more than once */
                        if (used_ports & port_mask)
-                               return false;
+                               ret = false;
 
                        used_ports |= port_mask;
                        break;
@@ -10754,7 +10793,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state)
        if (used_ports & used_mst_ports)
                return false;
 
-       return true;
+       return ret;
 }
 
 static void
@@ -12075,7 +12114,7 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
        struct drm_device *dev = crtc->base.dev;
 
        if (!dev->max_vblank_count)
-               return drm_crtc_accurate_vblank_count(&crtc->base);
+               return (u32)drm_crtc_accurate_vblank_count(&crtc->base);
 
        return dev->driver->get_vblank_counter(dev, crtc->pipe);
 }
@@ -12616,7 +12655,7 @@ static void add_rps_boost_after_vblank(struct drm_crtc *crtc,
 /**
  * intel_prepare_plane_fb - Prepare fb for usage on plane
  * @plane: drm plane to prepare for
- * @fb: framebuffer to prepare for presentation
+ * @new_state: the plane state being prepared
  *
  * Prepares a framebuffer for usage on a display plane.  Generally this
  * involves pinning the underlying object and updating the frontbuffer tracking
@@ -12695,7 +12734,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
        } else {
                struct i915_vma *vma;
 
-               vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
+               vma = intel_pin_and_fence_fb_obj(fb,
+                                                new_state->rotation,
+                                                &to_intel_plane_state(new_state)->flags);
                if (!IS_ERR(vma))
                        to_intel_plane_state(new_state)->vma = vma;
                else
@@ -12734,7 +12775,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 /**
  * intel_cleanup_plane_fb - Cleans up an fb after plane use
  * @plane: drm plane to clean up for
- * @fb: old framebuffer that was on plane
+ * @old_state: the state from the previous modeset
  *
  * Cleans up a framebuffer that has just been removed from a plane.
  *
@@ -12750,7 +12791,7 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
        vma = fetch_and_zero(&to_intel_plane_state(old_state)->vma);
        if (vma) {
                mutex_lock(&plane->dev->struct_mutex);
-               intel_unpin_fb_vma(vma);
+               intel_unpin_fb_vma(vma, to_intel_plane_state(old_state)->flags);
                mutex_unlock(&plane->dev->struct_mutex);
        }
 }
@@ -13111,7 +13152,9 @@ intel_legacy_cursor_update(struct drm_plane *plane,
                        goto out_unlock;
                }
        } else {
-               vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation);
+               vma = intel_pin_and_fence_fb_obj(fb,
+                                                new_plane_state->rotation,
+                                                &to_intel_plane_state(new_plane_state)->flags);
                if (IS_ERR(vma)) {
                        DRM_DEBUG_KMS("failed to pin object\n");
 
@@ -13142,7 +13185,8 @@ intel_legacy_cursor_update(struct drm_plane *plane,
 
        old_vma = fetch_and_zero(&to_intel_plane_state(old_plane_state)->vma);
        if (old_vma)
-               intel_unpin_fb_vma(old_vma);
+               intel_unpin_fb_vma(old_vma,
+                                  to_intel_plane_state(old_plane_state)->flags);
 
 out_unlock:
        mutex_unlock(&dev_priv->drm.struct_mutex);
@@ -13498,8 +13542,8 @@ enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)
        return to_intel_crtc(connector->base.state->crtc)->pipe;
 }
 
-int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
-                               struct drm_file *file)
+int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
+                                     struct drm_file *file)
 {
        struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
        struct drm_crtc *drmmode_crtc;
@@ -13947,7 +13991,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
         * gen2/3 display engine uses the fence if present,
         * so the tiling mode must match the fb modifier exactly.
         */
-       if (INTEL_INFO(dev_priv)->gen < 4 &&
+       if (INTEL_GEN(dev_priv) < 4 &&
            tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
                DRM_DEBUG_KMS("tiling_mode must match fb modifier exactly on gen2/3\n");
                goto err;
@@ -14162,7 +14206,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
 {
        intel_init_cdclk_hooks(dev_priv);
 
-       if (INTEL_INFO(dev_priv)->gen >= 9) {
+       if (INTEL_GEN(dev_priv) >= 9) {
                dev_priv->display.get_pipe_config = haswell_get_pipe_config;
                dev_priv->display.get_initial_plane_config =
                        skylake_get_initial_plane_config;
index f10a14330e7c9f196593bfea38f8c9e4d77a3e45..f20b25f98e5adf90bd7c0f3e6bb93493fbc5b32f 100644 (file)
@@ -258,7 +258,7 @@ static int cnl_max_source_rate(struct intel_dp *intel_dp)
        if (IS_CNL_WITH_PORT_F(dev_priv))
                return 810000;
 
-       /* For other SKUs, max rate on ports A and B is 5.4G */
+       /* For other SKUs, max rate on ports A and D is 5.4G */
        if (port == PORT_A || port == PORT_D)
                return 540000;
 
@@ -1467,7 +1467,7 @@ static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv,
 static i915_reg_t intel_aux_ctl_reg(struct drm_i915_private *dev_priv,
                                    enum port port)
 {
-       if (INTEL_INFO(dev_priv)->gen >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                return skl_aux_ctl_reg(dev_priv, port);
        else if (HAS_PCH_SPLIT(dev_priv))
                return ilk_aux_ctl_reg(dev_priv, port);
@@ -1478,7 +1478,7 @@ static i915_reg_t intel_aux_ctl_reg(struct drm_i915_private *dev_priv,
 static i915_reg_t intel_aux_data_reg(struct drm_i915_private *dev_priv,
                                     enum port port, int index)
 {
-       if (INTEL_INFO(dev_priv)->gen >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                return skl_aux_data_reg(dev_priv, port, index);
        else if (HAS_PCH_SPLIT(dev_priv))
                return ilk_aux_data_reg(dev_priv, port, index);
index 76473e9836c6003d85f46808afe5ea26b920ab15..c8e9e44e5981fe64d75028773ab2b9d3e5f61c71 100644 (file)
@@ -147,7 +147,7 @@ struct bxt_ddi_phy_info {
         */
        struct {
                /**
-                * @port: which port maps to this channel.
+                * @channel.port: which port maps to this channel.
                 */
                enum port port;
        } channel[2];
index 468ec1e90e16dab6bb451636719a95a22d8d6cf5..50874f4035cfe444f462c812e5aabf69016c36ca 100644 (file)
@@ -204,6 +204,7 @@ struct intel_fbdev {
        struct drm_fb_helper helper;
        struct intel_framebuffer *fb;
        struct i915_vma *vma;
+       unsigned long vma_flags;
        async_cookie_t cookie;
        int preferred_bpp;
 };
@@ -490,6 +491,8 @@ struct intel_atomic_state {
 struct intel_plane_state {
        struct drm_plane_state base;
        struct i915_vma *vma;
+       unsigned long flags;
+#define PLANE_HAS_FENCE BIT(0)
 
        struct {
                u32 offset;
@@ -1407,6 +1410,8 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv);
 void cnl_uninit_cdclk(struct drm_i915_private *dev_priv);
 void bxt_init_cdclk(struct drm_i915_private *dev_priv);
 void bxt_uninit_cdclk(struct drm_i915_private *dev_priv);
+void icl_init_cdclk(struct drm_i915_private *dev_priv);
+void icl_uninit_cdclk(struct drm_i915_private *dev_priv);
 void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv);
 void intel_update_max_cdclk(struct drm_i915_private *dev_priv);
 void intel_update_cdclk(struct drm_i915_private *dev_priv);
@@ -1455,8 +1460,8 @@ struct drm_display_mode *
 intel_encoder_current_mode(struct intel_encoder *encoder);
 
 enum pipe intel_get_pipe_from_connector(struct intel_connector *connector);
-int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
-                               struct drm_file *file_priv);
+int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
+                                     struct drm_file *file_priv);
 enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
                                             enum pipe pipe);
 static inline bool
@@ -1501,8 +1506,10 @@ void intel_release_load_detect_pipe(struct drm_connector *connector,
                                    struct intel_load_detect_pipe *old,
                                    struct drm_modeset_acquire_ctx *ctx);
 struct i915_vma *
-intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation);
-void intel_unpin_fb_vma(struct i915_vma *vma);
+intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
+                          unsigned int rotation,
+                          unsigned long *out_flags);
+void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags);
 struct drm_framebuffer *
 intel_framebuffer_create(struct drm_i915_gem_object *obj,
                         struct drm_mode_fb_cmd2 *mode_cmd);
@@ -2018,8 +2025,8 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
                             int usecs);
 struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
                                              enum pipe pipe, int plane);
-int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
-                             struct drm_file *file_priv);
+int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
+                                   struct drm_file *file_priv);
 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state);
 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state);
 void skl_update_plane(struct intel_plane *plane,
index 59c066ca14e5f576ce9104410b715d4e6c9d4d05..eb0c559b27156c0a49e31d342e865e7e88d1ea15 100644 (file)
@@ -245,7 +245,8 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder,
                intel_dvo->attached_connector->panel.fixed_mode;
        struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
 
-       /* If we have timings from the BIOS for the panel, put them in
+       /*
+        * If we have timings from the BIOS for the panel, put them in
         * to the adjusted mode.  The CRTC will be set up for this mode,
         * with the panel scaling set up to source from the H/VDisplay
         * of the original mode.
@@ -293,11 +294,6 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder,
        I915_WRITE(dvo_reg, dvo_val);
 }
 
-/**
- * Detect the output connection on our DVO device.
- *
- * Unimplemented.
- */
 static enum drm_connector_status
 intel_dvo_detect(struct drm_connector *connector, bool force)
 {
@@ -313,7 +309,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
        const struct drm_display_mode *fixed_mode =
                to_intel_connector(connector)->panel.fixed_mode;
 
-       /* We should probably have an i2c driver get_modes function for those
+       /*
+        * We should probably have an i2c driver get_modes function for those
         * devices which will have a fixed set of modes determined by the chip
         * (TV-out, for example), but for now with just TMDS and LVDS,
         * that's not the case.
@@ -371,7 +368,7 @@ static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
        .destroy = intel_dvo_enc_destroy,
 };
 
-/**
+/*
  * Attempts to get a fixed panel timing for LVDS (currently only the i830).
  *
  * Other chips with DVO LVDS will need to extend this to deal with the LVDS
@@ -443,7 +440,8 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
                uint32_t dpll[I915_MAX_PIPES];
                enum port port;
 
-               /* Allow the I2C driver info to specify the GPIO to be used in
+               /*
+                * Allow the I2C driver info to specify the GPIO to be used in
                 * special cases, but otherwise default to what's defined
                 * in the spec.
                 */
@@ -454,7 +452,8 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
                else
                        gpio = GMBUS_PIN_DPB;
 
-               /* Set up the I2C bus necessary for the chip we're probing.
+               /*
+                * Set up the I2C bus necessary for the chip we're probing.
                 * It appears that everything is on GPIOE except for panels
                 * on i830 laptops, which are on GPIOB (DVOA).
                 */
@@ -462,12 +461,14 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
 
                intel_dvo->dev = *dvo;
 
-               /* GMBUS NAK handling seems to be unstable, hence let the
+               /*
+                * GMBUS NAK handling seems to be unstable, hence let the
                 * transmitter detection run in bit banging mode for now.
                 */
                intel_gmbus_force_bit(i2c, true);
 
-               /* ns2501 requires the DVO 2x clock before it will
+               /*
+                * ns2501 requires the DVO 2x clock before it will
                 * respond to i2c accesses, so make sure we have
                 * have the clock enabled before we attempt to
                 * initialize the device.
@@ -525,7 +526,8 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
 
                intel_connector_attach_encoder(intel_connector, intel_encoder);
                if (dvo->type == INTEL_DVO_CHIP_LVDS) {
-                       /* For our LVDS chipsets, we should hopefully be able
+                       /*
+                        * For our LVDS chipsets, we should hopefully be able
                         * to dig the fixed panel mode out of the BIOS data.
                         * However, it's in a different format from the BIOS
                         * data on chipsets with integrated LVDS (stored in AIM
index 7eebfbb95e89974b450d633a4878c936a4b1c74a..f3c5100d629e91238934d61e95be4e323589aca8 100644 (file)
@@ -631,7 +631,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
         * Similarly the preempt context must always be available so that
         * we can interrupt the engine at any time.
         */
-       if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) {
+       if (engine->i915->preempt_context) {
                ring = engine->context_pin(engine,
                                           engine->i915->preempt_context);
                if (IS_ERR(ring)) {
@@ -656,7 +656,7 @@ int intel_engine_init_common(struct intel_engine_cs *engine)
 err_breadcrumbs:
        intel_engine_fini_breadcrumbs(engine);
 err_unpin_preempt:
-       if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
+       if (engine->i915->preempt_context)
                engine->context_unpin(engine, engine->i915->preempt_context);
 err_unpin_kernel:
        engine->context_unpin(engine, engine->i915->kernel_context);
@@ -686,12 +686,12 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
        if (engine->default_state)
                i915_gem_object_put(engine->default_state);
 
-       if (HAS_LOGICAL_RING_PREEMPTION(engine->i915))
+       if (engine->i915->preempt_context)
                engine->context_unpin(engine, engine->i915->preempt_context);
        engine->context_unpin(engine, engine->i915->kernel_context);
 }
 
-u64 intel_engine_get_active_head(struct intel_engine_cs *engine)
+u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
 {
        struct drm_i915_private *dev_priv = engine->i915;
        u64 acthd;
@@ -707,7 +707,7 @@ u64 intel_engine_get_active_head(struct intel_engine_cs *engine)
        return acthd;
 }
 
-u64 intel_engine_get_last_batch_head(struct intel_engine_cs *engine)
+u64 intel_engine_get_last_batch_head(const struct intel_engine_cs *engine)
 {
        struct drm_i915_private *dev_priv = engine->i915;
        u64 bbaddr;
@@ -1464,7 +1464,9 @@ static bool ring_is_idle(struct intel_engine_cs *engine)
        struct drm_i915_private *dev_priv = engine->i915;
        bool idle = true;
 
-       intel_runtime_pm_get(dev_priv);
+       /* If the whole device is asleep, the engine must be idle */
+       if (!intel_runtime_pm_get_if_in_use(dev_priv))
+               return true;
 
        /* First check that no commands are left in the ring */
        if ((I915_READ_HEAD(engine) & HEAD_ADDR) !=
@@ -1503,10 +1505,6 @@ bool intel_engine_is_idle(struct intel_engine_cs *engine)
        if (I915_SELFTEST_ONLY(engine->breadcrumbs.mock))
                return true;
 
-       /* Interrupt/tasklet pending? */
-       if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))
-               return false;
-
        /* Waiting to drain ELSP? */
        if (READ_ONCE(engine->execlists.active))
                return false;
@@ -1707,73 +1705,20 @@ static void hexdump(struct drm_printer *m, const void *buf, size_t len)
        }
 }
 
-void intel_engine_dump(struct intel_engine_cs *engine,
-                      struct drm_printer *m,
-                      const char *header, ...)
+static void intel_engine_print_registers(const struct intel_engine_cs *engine,
+                                        struct drm_printer *m)
 {
-       struct intel_breadcrumbs * const b = &engine->breadcrumbs;
-       const struct intel_engine_execlists * const execlists = &engine->execlists;
-       struct i915_gpu_error * const error = &engine->i915->gpu_error;
        struct drm_i915_private *dev_priv = engine->i915;
-       struct drm_i915_gem_request *rq;
-       struct rb_node *rb;
-       char hdr[80];
+       const struct intel_engine_execlists * const execlists =
+               &engine->execlists;
        u64 addr;
 
-       if (header) {
-               va_list ap;
-
-               va_start(ap, header);
-               drm_vprintf(m, header, &ap);
-               va_end(ap);
-       }
-
-       if (i915_terminally_wedged(&engine->i915->gpu_error))
-               drm_printf(m, "*** WEDGED ***\n");
-
-       drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms], inflight %d\n",
-                  intel_engine_get_seqno(engine),
-                  intel_engine_last_submit(engine),
-                  engine->hangcheck.seqno,
-                  jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp),
-                  engine->timeline->inflight_seqnos);
-       drm_printf(m, "\tReset count: %d (global %d)\n",
-                  i915_reset_engine_count(error, engine),
-                  i915_reset_count(error));
-
-       rcu_read_lock();
-
-       drm_printf(m, "\tRequests:\n");
-
-       rq = list_first_entry(&engine->timeline->requests,
-                             struct drm_i915_gem_request, link);
-       if (&rq->link != &engine->timeline->requests)
-               print_request(m, rq, "\t\tfirst  ");
-
-       rq = list_last_entry(&engine->timeline->requests,
-                            struct drm_i915_gem_request, link);
-       if (&rq->link != &engine->timeline->requests)
-               print_request(m, rq, "\t\tlast   ");
-
-       rq = i915_gem_find_active_request(engine);
-       if (rq) {
-               print_request(m, rq, "\t\tactive ");
-               drm_printf(m,
-                          "\t\t[head %04x, postfix %04x, tail %04x, batch 0x%08x_%08x]\n",
-                          rq->head, rq->postfix, rq->tail,
-                          rq->batch ? upper_32_bits(rq->batch->node.start) : ~0u,
-                          rq->batch ? lower_32_bits(rq->batch->node.start) : ~0u);
-       }
-
-       drm_printf(m, "\tRING_START: 0x%08x [0x%08x]\n",
-                  I915_READ(RING_START(engine->mmio_base)),
-                  rq ? i915_ggtt_offset(rq->ring->vma) : 0);
-       drm_printf(m, "\tRING_HEAD:  0x%08x [0x%08x]\n",
-                  I915_READ(RING_HEAD(engine->mmio_base)) & HEAD_ADDR,
-                  rq ? rq->ring->head : 0);
-       drm_printf(m, "\tRING_TAIL:  0x%08x [0x%08x]\n",
-                  I915_READ(RING_TAIL(engine->mmio_base)) & TAIL_ADDR,
-                  rq ? rq->ring->tail : 0);
+       drm_printf(m, "\tRING_START: 0x%08x\n",
+                  I915_READ(RING_START(engine->mmio_base)));
+       drm_printf(m, "\tRING_HEAD:  0x%08x\n",
+                  I915_READ(RING_HEAD(engine->mmio_base)) & HEAD_ADDR);
+       drm_printf(m, "\tRING_TAIL:  0x%08x\n",
+                  I915_READ(RING_TAIL(engine->mmio_base)) & TAIL_ADDR);
        drm_printf(m, "\tRING_CTL:   0x%08x%s\n",
                   I915_READ(RING_CTL(engine->mmio_base)),
                   I915_READ(RING_CTL(engine->mmio_base)) & (RING_WAIT | RING_WAIT_SEMAPHORE) ? " [waiting]" : "");
@@ -1782,6 +1727,11 @@ void intel_engine_dump(struct intel_engine_cs *engine,
                           I915_READ(RING_MI_MODE(engine->mmio_base)),
                           I915_READ(RING_MI_MODE(engine->mmio_base)) & (MODE_IDLE) ? " [idle]" : "");
        }
+
+       if (INTEL_GEN(dev_priv) >= 6) {
+               drm_printf(m, "\tRING_IMR: %08x\n", I915_READ_IMR(engine));
+       }
+
        if (HAS_LEGACY_SEMAPHORES(dev_priv)) {
                drm_printf(m, "\tSYNC_0: 0x%08x\n",
                           I915_READ(RING_SYNC_0(engine->mmio_base)));
@@ -1792,8 +1742,6 @@ void intel_engine_dump(struct intel_engine_cs *engine,
                                   I915_READ(RING_SYNC_2(engine->mmio_base)));
        }
 
-       rcu_read_unlock();
-
        addr = intel_engine_get_active_head(engine);
        drm_printf(m, "\tACTHD:  0x%08x_%08x\n",
                   upper_32_bits(addr), lower_32_bits(addr));
@@ -1855,10 +1803,13 @@ void intel_engine_dump(struct intel_engine_cs *engine,
 
                rcu_read_lock();
                for (idx = 0; idx < execlists_num_ports(execlists); idx++) {
+                       struct drm_i915_gem_request *rq;
                        unsigned int count;
 
                        rq = port_unpack(&execlists->port[idx], &count);
                        if (rq) {
+                               char hdr[80];
+
                                snprintf(hdr, sizeof(hdr),
                                         "\t\tELSP[%d] count=%d, rq: ",
                                         idx, count);
@@ -1877,6 +1828,77 @@ void intel_engine_dump(struct intel_engine_cs *engine,
                drm_printf(m, "\tPP_DIR_DCLV: 0x%08x\n",
                           I915_READ(RING_PP_DIR_DCLV(engine)));
        }
+}
+
+void intel_engine_dump(struct intel_engine_cs *engine,
+                      struct drm_printer *m,
+                      const char *header, ...)
+{
+       struct intel_breadcrumbs * const b = &engine->breadcrumbs;
+       const struct intel_engine_execlists * const execlists = &engine->execlists;
+       struct i915_gpu_error * const error = &engine->i915->gpu_error;
+       struct drm_i915_gem_request *rq;
+       struct rb_node *rb;
+
+       if (header) {
+               va_list ap;
+
+               va_start(ap, header);
+               drm_vprintf(m, header, &ap);
+               va_end(ap);
+       }
+
+       if (i915_terminally_wedged(&engine->i915->gpu_error))
+               drm_printf(m, "*** WEDGED ***\n");
+
+       drm_printf(m, "\tcurrent seqno %x, last %x, hangcheck %x [%d ms], inflight %d\n",
+                  intel_engine_get_seqno(engine),
+                  intel_engine_last_submit(engine),
+                  engine->hangcheck.seqno,
+                  jiffies_to_msecs(jiffies - engine->hangcheck.action_timestamp),
+                  engine->timeline->inflight_seqnos);
+       drm_printf(m, "\tReset count: %d (global %d)\n",
+                  i915_reset_engine_count(error, engine),
+                  i915_reset_count(error));
+
+       rcu_read_lock();
+
+       drm_printf(m, "\tRequests:\n");
+
+       rq = list_first_entry(&engine->timeline->requests,
+                             struct drm_i915_gem_request, link);
+       if (&rq->link != &engine->timeline->requests)
+               print_request(m, rq, "\t\tfirst  ");
+
+       rq = list_last_entry(&engine->timeline->requests,
+                            struct drm_i915_gem_request, link);
+       if (&rq->link != &engine->timeline->requests)
+               print_request(m, rq, "\t\tlast   ");
+
+       rq = i915_gem_find_active_request(engine);
+       if (rq) {
+               print_request(m, rq, "\t\tactive ");
+               drm_printf(m,
+                          "\t\t[head %04x, postfix %04x, tail %04x, batch 0x%08x_%08x]\n",
+                          rq->head, rq->postfix, rq->tail,
+                          rq->batch ? upper_32_bits(rq->batch->node.start) : ~0u,
+                          rq->batch ? lower_32_bits(rq->batch->node.start) : ~0u);
+               drm_printf(m, "\t\tring->start: 0x%08x\n",
+                          i915_ggtt_offset(rq->ring->vma));
+               drm_printf(m, "\t\tring->head:  0x%08x\n",
+                          rq->ring->head);
+               drm_printf(m, "\t\tring->tail:  0x%08x\n",
+                          rq->ring->tail);
+       }
+
+       rcu_read_unlock();
+
+       if (intel_runtime_pm_get_if_in_use(engine->i915)) {
+               intel_engine_print_registers(engine, m);
+               intel_runtime_pm_put(engine->i915);
+       } else {
+               drm_printf(m, "\tDevice is asleep; skipping register dump\n");
+       }
 
        spin_lock_irq(&engine->timeline->lock);
        list_for_each_entry(rq, &engine->timeline->requests, link)
@@ -1899,10 +1921,6 @@ void intel_engine_dump(struct intel_engine_cs *engine,
        }
        spin_unlock_irq(&b->rb_lock);
 
-       if (INTEL_GEN(dev_priv) >= 6) {
-               drm_printf(m, "\tRING_IMR: %08x\n", I915_READ_IMR(engine));
-       }
-
        drm_printf(m, "IRQ? 0x%lx (breadcrumbs? %s) (execlists? %s)\n",
                   engine->irq_posted,
                   yesno(test_bit(ENGINE_IRQ_BREADCRUMB,
index d7d1ac79c38a89cf73f64170241a6a51163e7439..f66f6fb5743d993f1af35ef6405aa877baba3dee 100644 (file)
@@ -183,7 +183,7 @@ static void g4x_fbc_activate(struct drm_i915_private *dev_priv)
        else
                dpfc_ctl |= DPFC_CTL_LIMIT_1X;
 
-       if (params->vma->fence) {
+       if (params->flags & PLANE_HAS_FENCE) {
                dpfc_ctl |= DPFC_CTL_FENCE_EN | params->vma->fence->id;
                I915_WRITE(DPFC_FENCE_YOFF, params->crtc.fence_y_offset);
        } else {
@@ -241,7 +241,7 @@ static void ilk_fbc_activate(struct drm_i915_private *dev_priv)
                break;
        }
 
-       if (params->vma->fence) {
+       if (params->flags & PLANE_HAS_FENCE) {
                dpfc_ctl |= DPFC_CTL_FENCE_EN;
                if (IS_GEN5(dev_priv))
                        dpfc_ctl |= params->vma->fence->id;
@@ -324,7 +324,7 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv)
                break;
        }
 
-       if (params->vma->fence) {
+       if (params->flags & PLANE_HAS_FENCE) {
                dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN;
                I915_WRITE(SNB_DPFC_CTL_SA,
                           SNB_CPU_FENCE_ENABLE |
@@ -753,6 +753,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
        struct drm_framebuffer *fb = plane_state->base.fb;
 
        cache->vma = NULL;
+       cache->flags = 0;
 
        cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
@@ -778,6 +779,9 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
        cache->fb.stride = fb->pitches[0];
 
        cache->vma = plane_state->vma;
+       cache->flags = plane_state->flags;
+       if (WARN_ON(cache->flags & PLANE_HAS_FENCE && !cache->vma->fence))
+               cache->flags &= ~PLANE_HAS_FENCE;
 }
 
 static bool intel_fbc_can_activate(struct intel_crtc *crtc)
@@ -816,7 +820,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc)
         * so have no fence associated with it) due to aperture constaints
         * at the time of pinning.
         */
-       if (!cache->vma->fence) {
+       if (!(cache->flags & PLANE_HAS_FENCE)) {
                fbc->no_fbc_reason = "framebuffer not tiled or fenced";
                return false;
        }
@@ -897,6 +901,7 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc,
        memset(params, 0, sizeof(*params));
 
        params->vma = cache->vma;
+       params->flags = cache->flags;
 
        params->crtc.pipe = crtc->pipe;
        params->crtc.i9xx_plane = to_intel_plane(crtc->base.primary)->i9xx_plane;
index da48af11eb6b8d521249c34fe55d689549496082..055f409f8b7587502a7e779bc40d4d53b11e85bc 100644 (file)
@@ -48,7 +48,8 @@
 static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev)
 {
        struct drm_i915_gem_object *obj = ifbdev->fb->obj;
-       unsigned int origin = ifbdev->vma->fence ? ORIGIN_GTT : ORIGIN_CPU;
+       unsigned int origin =
+               ifbdev->vma_flags & PLANE_HAS_FENCE ? ORIGIN_GTT : ORIGIN_CPU;
 
        intel_fb_obj_invalidate(obj, origin);
 }
@@ -177,6 +178,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
        struct fb_info *info;
        struct drm_framebuffer *fb;
        struct i915_vma *vma;
+       unsigned long flags = 0;
        bool prealloc = false;
        void __iomem *vaddr;
        int ret;
@@ -211,7 +213,9 @@ static int intelfb_create(struct drm_fb_helper *helper,
         * This also validates that any existing fb inherited from the
         * BIOS is suitable for own access.
         */
-       vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_MODE_ROTATE_0);
+       vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base,
+                                        DRM_MODE_ROTATE_0,
+                                        &flags);
        if (IS_ERR(vma)) {
                ret = PTR_ERR(vma);
                goto out_unlock;
@@ -268,6 +272,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
        DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x\n",
                      fb->width, fb->height, i915_ggtt_offset(vma));
        ifbdev->vma = vma;
+       ifbdev->vma_flags = flags;
 
        intel_runtime_pm_put(dev_priv);
        mutex_unlock(&dev->struct_mutex);
@@ -275,7 +280,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
        return 0;
 
 out_unpin:
-       intel_unpin_fb_vma(vma);
+       intel_unpin_fb_vma(vma, flags);
 out_unlock:
        intel_runtime_pm_put(dev_priv);
        mutex_unlock(&dev->struct_mutex);
@@ -513,7 +518,7 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
 
        if (ifbdev->vma) {
                mutex_lock(&ifbdev->helper.dev->struct_mutex);
-               intel_unpin_fb_vma(ifbdev->vma);
+               intel_unpin_fb_vma(ifbdev->vma, ifbdev->vma_flags);
                mutex_unlock(&ifbdev->helper.dev->struct_mutex);
        }
 
index 1f3a8786bbdc73447b9f7db630e86ddecf8d15bc..946766b62459d37930a2ce850899e7bba1eb11b2 100644 (file)
@@ -688,7 +688,7 @@ static void guc_dequeue(struct intel_engine_cs *engine)
                goto unlock;
 
        if (port_isset(port)) {
-               if (HAS_LOGICAL_RING_PREEMPTION(engine->i915)) {
+               if (engine->i915->preempt_context) {
                        struct guc_preempt_work *preempt_work =
                                &engine->i915->guc.preempt_work[engine->id];
 
@@ -747,6 +747,12 @@ done:
                execlists_set_active(execlists, EXECLISTS_ACTIVE_USER);
                guc_submit(engine);
        }
+
+       /* We must always keep the beast fed if we have work piled up */
+       GEM_BUG_ON(port_isset(execlists->port) &&
+                  !execlists_is_active(execlists, EXECLISTS_ACTIVE_USER));
+       GEM_BUG_ON(execlists->first && !port_isset(execlists->port));
+
 unlock:
        spin_unlock_irq(&engine->timeline->lock);
 }
@@ -832,10 +838,12 @@ static int guc_clients_doorbell_init(struct intel_guc *guc)
        if (ret)
                return ret;
 
-       ret = create_doorbell(guc->preempt_client);
-       if (ret) {
-               destroy_doorbell(guc->execbuf_client);
-               return ret;
+       if (guc->preempt_client) {
+               ret = create_doorbell(guc->preempt_client);
+               if (ret) {
+                       destroy_doorbell(guc->execbuf_client);
+                       return ret;
+               }
        }
 
        return 0;
@@ -848,8 +856,11 @@ static void guc_clients_doorbell_fini(struct intel_guc *guc)
         * Instead of trying (in vain) to communicate with it, let's just
         * cleanup the doorbell HW and our internal state.
         */
-       __destroy_doorbell(guc->preempt_client);
-       __update_doorbell_desc(guc->preempt_client, GUC_DOORBELL_INVALID);
+       if (guc->preempt_client) {
+               __destroy_doorbell(guc->preempt_client);
+               __update_doorbell_desc(guc->preempt_client,
+                                      GUC_DOORBELL_INVALID);
+       }
        __destroy_doorbell(guc->execbuf_client);
        __update_doorbell_desc(guc->execbuf_client, GUC_DOORBELL_INVALID);
 }
@@ -979,17 +990,19 @@ static int guc_clients_create(struct intel_guc *guc)
        }
        guc->execbuf_client = client;
 
-       client = guc_client_alloc(dev_priv,
-                                 INTEL_INFO(dev_priv)->ring_mask,
-                                 GUC_CLIENT_PRIORITY_KMD_HIGH,
-                                 dev_priv->preempt_context);
-       if (IS_ERR(client)) {
-               DRM_ERROR("Failed to create GuC client for preemption!\n");
-               guc_client_free(guc->execbuf_client);
-               guc->execbuf_client = NULL;
-               return PTR_ERR(client);
+       if (dev_priv->preempt_context) {
+               client = guc_client_alloc(dev_priv,
+                                         INTEL_INFO(dev_priv)->ring_mask,
+                                         GUC_CLIENT_PRIORITY_KMD_HIGH,
+                                         dev_priv->preempt_context);
+               if (IS_ERR(client)) {
+                       DRM_ERROR("Failed to create GuC client for preemption!\n");
+                       guc_client_free(guc->execbuf_client);
+                       guc->execbuf_client = NULL;
+                       return PTR_ERR(client);
+               }
+               guc->preempt_client = client;
        }
-       guc->preempt_client = client;
 
        return 0;
 }
@@ -998,10 +1011,11 @@ static void guc_clients_destroy(struct intel_guc *guc)
 {
        struct intel_guc_client *client;
 
-       client = fetch_and_zero(&guc->execbuf_client);
-       guc_client_free(client);
-
        client = fetch_and_zero(&guc->preempt_client);
+       if (client)
+               guc_client_free(client);
+
+       client = fetch_and_zero(&guc->execbuf_client);
        guc_client_free(client);
 }
 
@@ -1160,7 +1174,8 @@ int intel_guc_submission_enable(struct intel_guc *guc)
        GEM_BUG_ON(!guc->execbuf_client);
 
        guc_reset_wq(guc->execbuf_client);
-       guc_reset_wq(guc->preempt_client);
+       if (guc->preempt_client)
+               guc_reset_wq(guc->preempt_client);
 
        err = intel_guc_sample_forcewake(guc);
        if (err)
index 8ed05182f94448fda9ca53487ea85e9f181d9e15..ef9a05d8e5a9beef5d7724cbbdb3b0934c500a1d 100644 (file)
@@ -118,7 +118,8 @@ void intel_huc_init_early(struct intel_huc *huc)
 
 /**
  * huc_ucode_xfer() - DMA's the firmware
- * @dev_priv: the drm_i915_private device
+ * @huc_fw: the firmware descriptor
+ * @vma: the firmware image (bound into the GGTT)
  *
  * Transfer the firmware image to RAM for execution by the microcontroller.
  *
index 5809b29044fc573401f6116bb45762fc07e71596..6269750e2b547c3db8969e54c6ab03116a1e112f 100644 (file)
@@ -74,7 +74,6 @@
 static struct platform_device *
 lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
 {
-       int ret;
        struct drm_device *dev = &dev_priv->drm;
        struct platform_device_info pinfo = {};
        struct resource *rsc;
@@ -119,24 +118,19 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
        spin_lock_init(&pdata->lpe_audio_slock);
 
        platdev = platform_device_register_full(&pinfo);
+       kfree(rsc);
+       kfree(pdata);
+
        if (IS_ERR(platdev)) {
-               ret = PTR_ERR(platdev);
                DRM_ERROR("Failed to allocate LPE audio platform device\n");
-               goto err;
+               return platdev;
        }
 
-       kfree(rsc);
-
        pm_runtime_forbid(&platdev->dev);
        pm_runtime_set_active(&platdev->dev);
        pm_runtime_enable(&platdev->dev);
 
        return platdev;
-
-err:
-       kfree(rsc);
-       kfree(pdata);
-       return ERR_PTR(ret);
 }
 
 static void lpe_audio_platdev_destroy(struct drm_i915_private *dev_priv)
index 380c0838d8b3f2e7169897e4755e4110b2970307..9b6d781b22ec10c5adcce18de19613c97dfbb07f 100644 (file)
 #define EXECLISTS_REQUEST_SIZE 64 /* bytes */
 #define WA_TAIL_DWORDS 2
 #define WA_TAIL_BYTES (sizeof(u32) * WA_TAIL_DWORDS)
-#define PREEMPT_ID 0x1
 
 static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
                                            struct intel_engine_cs *engine);
@@ -448,7 +447,8 @@ static void inject_preempt_context(struct intel_engine_cs *engine)
                &engine->i915->preempt_context->engine[engine->id];
        unsigned int n;
 
-       GEM_BUG_ON(engine->i915->preempt_context->hw_id != PREEMPT_ID);
+       GEM_BUG_ON(engine->execlists.preempt_complete_status !=
+                  upper_32_bits(ce->lrc_desc));
        GEM_BUG_ON(!IS_ALIGNED(ce->ring->size, WA_TAIL_BYTES));
 
        memset(ce->ring->vaddr + ce->ring->tail, 0, WA_TAIL_BYTES);
@@ -528,7 +528,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_HWACK))
                        goto unlock;
 
-               if (HAS_LOGICAL_RING_PREEMPTION(engine->i915) &&
+               if (engine->i915->preempt_context &&
                    rb_entry(rb, struct i915_priolist, node)->priority >
                    max(last->priotree.priority, 0)) {
                        /*
@@ -642,6 +642,10 @@ done:
        execlists->first = rb;
        if (submit)
                port_assign(port, last);
+
+       /* We must always keep the beast fed if we have work piled up */
+       GEM_BUG_ON(execlists->first && !port_isset(execlists->port));
+
 unlock:
        spin_unlock_irq(&engine->timeline->lock);
 
@@ -649,6 +653,9 @@ unlock:
                execlists_set_active(execlists, EXECLISTS_ACTIVE_USER);
                execlists_submit_ports(engine);
        }
+
+       GEM_BUG_ON(port_isset(execlists->port) &&
+                  !execlists_is_active(execlists, EXECLISTS_ACTIVE_USER));
 }
 
 void
@@ -844,7 +851,7 @@ static void execlists_submission_tasklet(unsigned long data)
                        GEM_BUG_ON(status & GEN8_CTX_STATUS_IDLE_ACTIVE);
 
                        if (status & GEN8_CTX_STATUS_COMPLETE &&
-                           buf[2*head + 1] == PREEMPT_ID) {
+                           buf[2*head + 1] == execlists->preempt_complete_status) {
                                GEM_TRACE("%s preempt-idle\n", engine->name);
 
                                execlists_cancel_port_requests(execlists);
@@ -1963,6 +1970,12 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine)
        engine->unpark = NULL;
 
        engine->flags |= I915_ENGINE_SUPPORTS_STATS;
+
+       engine->i915->caps.scheduler =
+               I915_SCHEDULER_CAP_ENABLED |
+               I915_SCHEDULER_CAP_PRIORITY;
+       if (engine->i915->preempt_context)
+               engine->i915->caps.scheduler |= I915_SCHEDULER_CAP_PREEMPTION;
 }
 
 static void
@@ -2039,6 +2052,11 @@ static int logical_ring_init(struct intel_engine_cs *engine)
        engine->execlists.elsp =
                engine->i915->regs + i915_mmio_reg_offset(RING_ELSP(engine));
 
+       engine->execlists.preempt_complete_status = ~0u;
+       if (engine->i915->preempt_context)
+               engine->execlists.preempt_complete_status =
+                       upper_32_bits(engine->i915->preempt_context->engine[engine->id].lrc_desc);
+
        return 0;
 
 error:
@@ -2301,7 +2319,7 @@ populate_lr_context(struct i915_gem_context *ctx,
        if (!engine->default_state)
                regs[CTX_CONTEXT_CONTROL + 1] |=
                        _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
-       if (ctx->hw_id == PREEMPT_ID)
+       if (ctx == ctx->i915->preempt_context)
                regs[CTX_CONTEXT_CONTROL + 1] |=
                        _MASKED_BIT_ENABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
                                           CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT);
index ef80499113ee374e64f696228bc9d974eceb2957..d35d2d50f5951542bc58ec8bd19a51952300bb16 100644 (file)
@@ -189,7 +189,7 @@ static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
        /* Convert from 100ms to 100us units */
        pps->t4 = val * 1000;
 
-       if (INTEL_INFO(dev_priv)->gen <= 4 &&
+       if (INTEL_GEN(dev_priv) <= 4 &&
            pps->t1_t2 == 0 && pps->t5 == 0 && pps->t3 == 0 && pps->tx == 0) {
                DRM_DEBUG_KMS("Panel power timings uninitialized, "
                              "setting defaults\n");
@@ -268,7 +268,9 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder,
        /* set the corresponsding LVDS_BORDER bit */
        temp &= ~LVDS_BORDER_ENABLE;
        temp |= pipe_config->gmch_pfit.lvds_border_bits;
-       /* Set the B0-B3 data pairs corresponding to whether we're going to
+
+       /*
+        * Set the B0-B3 data pairs corresponding to whether we're going to
         * set the DPLLs for dual-channel mode or not.
         */
        if (lvds_encoder->is_dual_link)
@@ -276,7 +278,8 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder,
        else
                temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
 
-       /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
+       /*
+        * It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
         * appropriately here, but we need to look more thoroughly into how
         * panels behave in the two modes. For now, let's just maintain the
         * value we got from the BIOS.
@@ -284,12 +287,16 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder,
        temp &= ~LVDS_A3_POWER_MASK;
        temp |= lvds_encoder->a3_power;
 
-       /* Set the dithering flag on LVDS as needed, note that there is no
+       /*
+        * Set the dithering flag on LVDS as needed, note that there is no
         * special lvds dither control bit on pch-split platforms, dithering is
-        * only controlled through the PIPECONF reg. */
+        * only controlled through the PIPECONF reg.
+        */
        if (IS_GEN4(dev_priv)) {
-               /* Bspec wording suggests that LVDS port dithering only exists
-                * for 18bpp panels. */
+               /*
+                * Bspec wording suggests that LVDS port dithering only exists
+                * for 18bpp panels.
+                */
                if (pipe_config->dither && pipe_config->pipe_bpp == 18)
                        temp |= LVDS_ENABLE_DITHER;
                else
@@ -304,7 +311,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder,
        I915_WRITE(lvds_encoder->reg, temp);
 }
 
-/**
+/*
  * Sets the power state for the panel.
  */
 static void intel_enable_lvds(struct intel_encoder *encoder,
@@ -441,7 +448,7 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder,
        return true;
 }
 
-/**
+/*
  * Detect the LVDS connection.
  *
  * Since LVDS doesn't have hotlug, we use the lid as a proxy.  Open means
@@ -464,7 +471,7 @@ intel_lvds_detect(struct drm_connector *connector, bool force)
        return connector_status_connected;
 }
 
-/**
+/*
  * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
  */
 static int intel_lvds_get_modes(struct drm_connector *connector)
@@ -893,7 +900,8 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
        if (dmi_check_system(intel_dual_link_lvds))
                return true;
 
-       /* BIOS should set the proper LVDS register value at boot, but
+       /*
+        * BIOS should set the proper LVDS register value at boot, but
         * in reality, it doesn't set the value when the lid is closed;
         * we need to check "the value to be set" in VBT when LVDS
         * register is uninitialized.
@@ -907,13 +915,17 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
 
 static bool intel_lvds_supported(struct drm_i915_private *dev_priv)
 {
-       /* With the introduction of the PCH we gained a dedicated
-        * LVDS presence pin, use it. */
+       /*
+        * With the introduction of the PCH we gained a dedicated
+        * LVDS presence pin, use it.
+        */
        if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))
                return true;
 
-       /* Otherwise LVDS was only attached to mobile products,
-        * except for the inglorious 830gm */
+       /*
+        * Otherwise LVDS was only attached to mobile products,
+        * except for the inglorious 830gm
+        */
        if (INTEL_GEN(dev_priv) <= 4 &&
            IS_MOBILE(dev_priv) && !IS_I830(dev_priv))
                return true;
@@ -923,7 +935,7 @@ static bool intel_lvds_supported(struct drm_i915_private *dev_priv)
 
 /**
  * intel_lvds_init - setup LVDS connectors on this device
- * @dev: drm device
+ * @dev_priv: i915 device
  *
  * Create the connector, register the LVDS DDC bus, and try to figure out what
  * modes we can display on the LVDS panel (if present).
index f4c46b0b8f0aeb6d42ecb31031053bfd5182485f..abb7a8c1e340c036c5c29338c0bb5c526de1ebca 100644 (file)
@@ -187,7 +187,7 @@ static bool get_mocs_settings(struct drm_i915_private *dev_priv,
                table->table = broxton_mocs_table;
                result = true;
        } else {
-               WARN_ONCE(INTEL_INFO(dev_priv)->gen >= 9,
+               WARN_ONCE(INTEL_GEN(dev_priv) >= 9,
                          "Platform that should have a MOCS table does not.\n");
        }
 
index 41e9465d44a8128c0463d024be40066212819d79..89f568e739ee8ce3b6330800081dde4de895c7f2 100644 (file)
@@ -801,7 +801,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
 
        atomic_inc(&dev_priv->gpu_error.pending_fb_pin);
 
-       vma = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL);
+       vma = i915_gem_object_pin_to_display_plane(new_bo,
+                                                  0, NULL, PIN_MAPPABLE);
        if (IS_ERR(vma)) {
                ret = PTR_ERR(vma);
                goto out_pin_section;
index e702a6487aa9af532d685e7b18ea4a513935d30d..41d00b1603e304ff5694cc2bd8ec8daee80bc80c 100644 (file)
@@ -397,8 +397,11 @@ intel_panel_detect(struct drm_i915_private *dev_priv)
 
 /**
  * scale - scale values from one range to another
- *
  * @source_val: value in range [@source_min..@source_max]
+ * @source_min: minimum legal value for @source_val
+ * @source_max: maximum legal value for @source_val
+ * @target_min: corresponding target value for @source_min
+ * @target_max: corresponding target value for @source_max
  *
  * Return @source_val in range [@source_min..@source_max] scaled to range
  * [@target_min..@target_max].
@@ -416,8 +419,9 @@ static uint32_t scale(uint32_t source_val,
        source_val = clamp(source_val, source_min, source_max);
 
        /* avoid overflows */
-       target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) *
-                       (target_max - target_min), source_max - source_min);
+       target_val = mul_u32_u32(source_val - source_min,
+                                target_max - target_min);
+       target_val = DIV_ROUND_CLOSEST_ULL(target_val, source_max - source_min);
        target_val += target_min;
 
        return target_val;
@@ -497,7 +501,7 @@ static u32 i9xx_get_backlight(struct intel_connector *connector)
        u32 val;
 
        val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK;
-       if (INTEL_INFO(dev_priv)->gen < 4)
+       if (INTEL_GEN(dev_priv) < 4)
                val >>= 1;
 
        if (panel->backlight.combination_mode) {
index eb68abf6a8e96727f916129406870ea01772af6a..abf80e462833d7d6ae106d9b8bd9c229335dce01 100644 (file)
@@ -729,6 +729,7 @@ static unsigned int intel_wm_method2(unsigned int pixel_rate,
  * intel_calculate_wm - calculate watermark level
  * @pixel_rate: pixel clock
  * @wm: chip FIFO params
+ * @fifo_size: size of the FIFO buffer
  * @cpp: bytes per pixel
  * @latency_ns: memory latency for the platform
  *
@@ -2916,10 +2917,6 @@ static void intel_fixup_cur_wm_latency(struct drm_i915_private *dev_priv,
        /* ILK cursor LP0 latency is 1300 ns */
        if (IS_GEN5(dev_priv))
                wm[0] = 13;
-
-       /* WaDoubleCursorLP3Latency:ivb */
-       if (IS_IVYBRIDGE(dev_priv))
-               wm[3] *= 2;
 }
 
 int ilk_wm_max_level(const struct drm_i915_private *dev_priv)
@@ -4596,7 +4593,8 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
                min_disp_buf_needed = res_blocks;
        }
 
-       if (res_blocks >= ddb_allocation || res_lines > 31 ||
+       if ((level > 0 && res_lines > 31) ||
+           res_blocks >= ddb_allocation ||
            min_disp_buf_needed >= ddb_allocation) {
                *enabled = false;
 
@@ -4617,8 +4615,9 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
                }
        }
 
+       /* The number of lines are ignored for the level 0 watermark. */
+       *out_lines = level ? res_lines : 0;
        *out_blocks = res_blocks;
-       *out_lines = res_lines;
        *enabled = true;
 
        return 0;
@@ -4710,6 +4709,7 @@ static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
        if (!dev_priv->ipc_enabled)
                goto exit;
 
+       trans_min = 0;
        if (INTEL_GEN(dev_priv) >= 10)
                trans_min = 4;
 
@@ -5864,6 +5864,7 @@ void ilk_wm_get_hw_state(struct drm_device *dev)
 
 /**
  * intel_update_watermarks - update FIFO watermark values based on current modes
+ * @crtc: the #intel_crtc on which to compute the WM
  *
  * Calculate watermark values for the various WM regs based on current mode
  * and plane configuration.
@@ -6372,12 +6373,15 @@ void gen6_rps_boost(struct drm_i915_gem_request *rq,
        if (!rps->enabled)
                return;
 
+       if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags))
+               return;
+
+       /* Serializes with i915_gem_request_retire() */
        boost = false;
        spin_lock_irqsave(&rq->lock, flags);
-       if (!rq->waitboost && !i915_gem_request_completed(rq)) {
-               atomic_inc(&rps->num_waiters);
+       if (!rq->waitboost && !dma_fence_is_signaled_locked(&rq->fence)) {
+               boost = !atomic_fetch_inc(&rps->num_waiters);
                rq->waitboost = true;
-               boost = true;
        }
        spin_unlock_irqrestore(&rq->lock, flags);
        if (!boost)
@@ -6938,7 +6942,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
                         * No floor required for ring frequency on SKL.
                         */
                        ring_freq = gpu_freq;
-               } else if (INTEL_INFO(dev_priv)->gen >= 8) {
+               } else if (INTEL_GEN(dev_priv) >= 8) {
                        /* max(2 * GT, DDR). NB: GT is 50MHz units */
                        ring_freq = max(min_ring_freq, gpu_freq);
                } else if (IS_HASWELL(dev_priv)) {
@@ -7549,7 +7553,7 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
 {
        unsigned long val;
 
-       if (INTEL_INFO(dev_priv)->gen != 5)
+       if (!IS_GEN5(dev_priv))
                return 0;
 
        spin_lock_irq(&mchdev_lock);
@@ -7633,7 +7637,7 @@ static void __i915_update_gfx_val(struct drm_i915_private *dev_priv)
 
 void i915_update_gfx_val(struct drm_i915_private *dev_priv)
 {
-       if (INTEL_INFO(dev_priv)->gen != 5)
+       if (!IS_GEN5(dev_priv))
                return;
 
        spin_lock_irq(&mchdev_lock);
@@ -7684,7 +7688,7 @@ unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
 {
        unsigned long val;
 
-       if (INTEL_INFO(dev_priv)->gen != 5)
+       if (!IS_GEN5(dev_priv))
                return 0;
 
        spin_lock_irq(&mchdev_lock);
@@ -9415,15 +9419,16 @@ static u64 vlv_residency_raw(struct drm_i915_private *dev_priv,
                             const i915_reg_t reg)
 {
        u32 lower, upper, tmp;
-       unsigned long flags;
        int loop = 2;
 
-       /* The register accessed do not need forcewake. We borrow
+       /*
+        * The register accessed do not need forcewake. We borrow
         * uncore lock to prevent concurrent access to range reg.
         */
-       spin_lock_irqsave(&dev_priv->uncore.lock, flags);
+       lockdep_assert_held(&dev_priv->uncore.lock);
 
-       /* vlv and chv residency counters are 40 bits in width.
+       /*
+        * vlv and chv residency counters are 40 bits in width.
         * With a control bit, we can choose between upper or lower
         * 32bit window into this counter.
         *
@@ -9447,29 +9452,49 @@ static u64 vlv_residency_raw(struct drm_i915_private *dev_priv,
                upper = I915_READ_FW(reg);
        } while (upper != tmp && --loop);
 
-       /* Everywhere else we always use VLV_COUNTER_CONTROL with the
+       /*
+        * Everywhere else we always use VLV_COUNTER_CONTROL with the
         * VLV_COUNT_RANGE_HIGH bit set - so it is safe to leave it set
         * now.
         */
 
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
-
        return lower | (u64)upper << 8;
 }
 
 u64 intel_rc6_residency_ns(struct drm_i915_private *dev_priv,
                           const i915_reg_t reg)
 {
-       u64 time_hw;
+       u64 time_hw, prev_hw, overflow_hw;
+       unsigned int fw_domains;
+       unsigned long flags;
+       unsigned int i;
        u32 mul, div;
 
        if (!HAS_RC6(dev_priv))
                return 0;
 
+       /*
+        * Store previous hw counter values for counter wrap-around handling.
+        *
+        * There are only four interesting registers and they live next to each
+        * other so we can use the relative address, compared to the smallest
+        * one as the index into driver storage.
+        */
+       i = (i915_mmio_reg_offset(reg) -
+            i915_mmio_reg_offset(GEN6_GT_GFX_RC6_LOCKED)) / sizeof(u32);
+       if (WARN_ON_ONCE(i >= ARRAY_SIZE(dev_priv->gt_pm.rc6.cur_residency)))
+               return 0;
+
+       fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg, FW_REG_READ);
+
+       spin_lock_irqsave(&dev_priv->uncore.lock, flags);
+       intel_uncore_forcewake_get__locked(dev_priv, fw_domains);
+
        /* On VLV and CHV, residency time is in CZ units rather than 1.28us */
        if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
                mul = 1000000;
                div = dev_priv->czclk_freq;
+               overflow_hw = BIT_ULL(40);
                time_hw = vlv_residency_raw(dev_priv, reg);
        } else {
                /* 833.33ns units on Gen9LP, 1.28us elsewhere. */
@@ -9481,10 +9506,33 @@ u64 intel_rc6_residency_ns(struct drm_i915_private *dev_priv,
                        div = 1;
                }
 
-               time_hw = I915_READ(reg);
+               overflow_hw = BIT_ULL(32);
+               time_hw = I915_READ_FW(reg);
        }
 
-       return DIV_ROUND_UP_ULL(time_hw * mul, div);
+       /*
+        * Counter wrap handling.
+        *
+        * But relying on a sufficient frequency of queries otherwise counters
+        * can still wrap.
+        */
+       prev_hw = dev_priv->gt_pm.rc6.prev_hw_residency[i];
+       dev_priv->gt_pm.rc6.prev_hw_residency[i] = time_hw;
+
+       /* RC6 delta from last sample. */
+       if (time_hw >= prev_hw)
+               time_hw -= prev_hw;
+       else
+               time_hw += overflow_hw - prev_hw;
+
+       /* Add delta to RC6 extended raw driver copy. */
+       time_hw += dev_priv->gt_pm.rc6.cur_residency[i];
+       dev_priv->gt_pm.rc6.cur_residency[i] = time_hw;
+
+       intel_uncore_forcewake_put__locked(dev_priv, fw_domains);
+       spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
+
+       return mul_u64_u32_div(time_hw, mul, div);
 }
 
 u32 intel_get_cagf(struct drm_i915_private *dev_priv, u32 rpstat)
index e9feffdea899cf869f192263695f02384e23daa6..2ef374f936b988ecf0f64e730d82e7fa119d31e9 100644 (file)
@@ -126,7 +126,7 @@ static void vlv_psr_enable_sink(struct intel_dp *intel_dp)
 static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv,
                                       enum port port)
 {
-       if (INTEL_INFO(dev_priv)->gen >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                return DP_AUX_CH_CTL(port);
        else
                return EDP_PSR_AUX_CTL;
@@ -135,7 +135,7 @@ static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv,
 static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv,
                                        enum port port, int index)
 {
-       if (INTEL_INFO(dev_priv)->gen >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                return DP_AUX_CH_DATA(port, index);
        else
                return EDP_PSR_AUX_DATA(index);
index e2085820b586bfd722765ef6bb79022ca719af78..5718f37160c593fede8eabe8ebe8cf1a63ef4abc 100644 (file)
@@ -137,7 +137,7 @@ gen4_render_ring_flush(struct drm_i915_gem_request *req, u32 mode)
        return 0;
 }
 
-/**
+/*
  * Emits a PIPE_CONTROL with a non-zero post-sync operation, for
  * implementing two workarounds on gen6.  From section 1.4.7.1
  * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1:
@@ -453,13 +453,13 @@ static int init_ring_common(struct intel_engine_cs *engine)
 
        if (!stop_ring(engine)) {
                /* G45 ring initialization often fails to reset head to zero */
-               DRM_DEBUG_KMS("%s head not reset to zero "
-                             "ctl %08x head %08x tail %08x start %08x\n",
-                             engine->name,
-                             I915_READ_CTL(engine),
-                             I915_READ_HEAD(engine),
-                             I915_READ_TAIL(engine),
-                             I915_READ_START(engine));
+               DRM_DEBUG_DRIVER("%s head not reset to zero "
+                               "ctl %08x head %08x tail %08x start %08x\n",
+                               engine->name,
+                               I915_READ_CTL(engine),
+                               I915_READ_HEAD(engine),
+                               I915_READ_TAIL(engine),
+                               I915_READ_START(engine));
 
                if (!stop_ring(engine)) {
                        DRM_ERROR("failed to set %s head to zero "
@@ -492,8 +492,8 @@ static int init_ring_common(struct intel_engine_cs *engine)
 
        /* WaClearRingBufHeadRegAtInit:ctg,elk */
        if (I915_READ_HEAD(engine))
-               DRM_DEBUG("%s initialization failed [head=%08x], fudging\n",
-                         engine->name, I915_READ_HEAD(engine));
+               DRM_DEBUG_DRIVER("%s initialization failed [head=%08x], fudging\n",
+                                engine->name, I915_READ_HEAD(engine));
 
        intel_ring_update_space(ring);
        I915_WRITE_HEAD(engine, ring->head);
@@ -655,7 +655,7 @@ static int init_render_ring(struct intel_engine_cs *engine)
        if (IS_GEN(dev_priv, 6, 7))
                I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING));
 
-       if (INTEL_INFO(dev_priv)->gen >= 6)
+       if (INTEL_GEN(dev_priv) >= 6)
                I915_WRITE_IMR(engine, ~engine->irq_keep_mask);
 
        return init_workarounds_ring(engine);
@@ -729,14 +729,6 @@ static void i9xx_emit_breadcrumb(struct drm_i915_gem_request *req, u32 *cs)
 
 static const int i9xx_emit_breadcrumb_sz = 4;
 
-/**
- * gen6_sema_emit_breadcrumb - Update the semaphore mailbox registers
- *
- * @request - request to write to the ring
- *
- * Update the mailbox registers in the *other* rings with the current seqno.
- * This acts like a signal in the canonical semaphore.
- */
 static void gen6_sema_emit_breadcrumb(struct drm_i915_gem_request *req, u32 *cs)
 {
        return i9xx_emit_breadcrumb(req,
index a0e7a6c2a57cd8f0b66f27e7e5dcc874857fd649..51523ad049dec71c899fafbb8399f1cec0b1ec06 100644 (file)
@@ -279,6 +279,11 @@ struct intel_engine_execlists {
         * @csb_use_mmio: access csb through mmio, instead of hwsp
         */
        bool csb_use_mmio;
+
+       /**
+        * @preempt_complete_status: expected CSB upon completing preemption
+        */
+       u32 preempt_complete_status;
 };
 
 #define INTEL_ENGINE_CS_MAX_NAME 8
@@ -654,7 +659,7 @@ intel_engine_flag(const struct intel_engine_cs *engine)
 }
 
 static inline u32
-intel_read_status_page(struct intel_engine_cs *engine, int reg)
+intel_read_status_page(const struct intel_engine_cs *engine, int reg)
 {
        /* Ensure that the compiler doesn't optimize away the load. */
        return READ_ONCE(engine->status_page.page_addr[reg]);
@@ -812,8 +817,8 @@ int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine);
 int intel_init_blt_ring_buffer(struct intel_engine_cs *engine);
 int intel_init_vebox_ring_buffer(struct intel_engine_cs *engine);
 
-u64 intel_engine_get_active_head(struct intel_engine_cs *engine);
-u64 intel_engine_get_last_batch_head(struct intel_engine_cs *engine);
+u64 intel_engine_get_active_head(const struct intel_engine_cs *engine);
+u64 intel_engine_get_last_batch_head(const struct intel_engine_cs *engine);
 
 static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine)
 {
index 70e659772a7ae9ce0a1d7efc12d3f2668cb1744f..b7924feb9f27b14921589313548a9d9ebfc5cbe1 100644 (file)
@@ -2646,6 +2646,48 @@ static void gen9_dbuf_disable(struct drm_i915_private *dev_priv)
                DRM_ERROR("DBuf power disable timeout!\n");
 }
 
+/*
+ * TODO: we shouldn't always enable DBUF_CTL_S2, we should only enable it when
+ * needed and keep it disabled as much as possible.
+ */
+static void icl_dbuf_enable(struct drm_i915_private *dev_priv)
+{
+       I915_WRITE(DBUF_CTL_S1, I915_READ(DBUF_CTL_S1) | DBUF_POWER_REQUEST);
+       I915_WRITE(DBUF_CTL_S2, I915_READ(DBUF_CTL_S2) | DBUF_POWER_REQUEST);
+       POSTING_READ(DBUF_CTL_S2);
+
+       udelay(10);
+
+       if (!(I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) ||
+           !(I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE))
+               DRM_ERROR("DBuf power enable timeout\n");
+}
+
+static void icl_dbuf_disable(struct drm_i915_private *dev_priv)
+{
+       I915_WRITE(DBUF_CTL_S1, I915_READ(DBUF_CTL_S1) & ~DBUF_POWER_REQUEST);
+       I915_WRITE(DBUF_CTL_S2, I915_READ(DBUF_CTL_S2) & ~DBUF_POWER_REQUEST);
+       POSTING_READ(DBUF_CTL_S2);
+
+       udelay(10);
+
+       if ((I915_READ(DBUF_CTL_S1) & DBUF_POWER_STATE) ||
+           (I915_READ(DBUF_CTL_S2) & DBUF_POWER_STATE))
+               DRM_ERROR("DBuf power disable timeout!\n");
+}
+
+static void icl_mbus_init(struct drm_i915_private *dev_priv)
+{
+       uint32_t val;
+
+       val = MBUS_ABOX_BT_CREDIT_POOL1(16) |
+             MBUS_ABOX_BT_CREDIT_POOL2(16) |
+             MBUS_ABOX_B_CREDIT(1) |
+             MBUS_ABOX_BW_CREDIT(1);
+
+       I915_WRITE(MBUS_ABOX_CTL, val);
+}
+
 static void skl_display_core_init(struct drm_i915_private *dev_priv,
                                   bool resume)
 {
@@ -2794,12 +2836,19 @@ static const struct cnl_procmon {
                { .dw1 = 0x00440000, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1, },
 };
 
-static void cnl_set_procmon_ref_values(struct drm_i915_private *dev_priv)
+/*
+ * CNL has just one set of registers, while ICL has two sets: one for port A and
+ * the other for port B. The CNL registers are equivalent to the ICL port A
+ * registers, that's why we call the ICL macros even though the function has CNL
+ * on its name.
+ */
+static void cnl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
+                                      enum port port)
 {
        const struct cnl_procmon *procmon;
        u32 val;
 
-       val = I915_READ(CNL_PORT_COMP_DW3);
+       val = I915_READ(ICL_PORT_COMP_DW3(port));
        switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) {
        default:
                MISSING_CASE(val);
@@ -2820,13 +2869,13 @@ static void cnl_set_procmon_ref_values(struct drm_i915_private *dev_priv)
                break;
        }
 
-       val = I915_READ(CNL_PORT_COMP_DW1);
+       val = I915_READ(ICL_PORT_COMP_DW1(port));
        val &= ~((0xff << 16) | 0xff);
        val |= procmon->dw1;
-       I915_WRITE(CNL_PORT_COMP_DW1, val);
+       I915_WRITE(ICL_PORT_COMP_DW1(port), val);
 
-       I915_WRITE(CNL_PORT_COMP_DW9, procmon->dw9);
-       I915_WRITE(CNL_PORT_COMP_DW10, procmon->dw10);
+       I915_WRITE(ICL_PORT_COMP_DW9(port), procmon->dw9);
+       I915_WRITE(ICL_PORT_COMP_DW10(port), procmon->dw10);
 }
 
 static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume)
@@ -2847,7 +2896,8 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume
        val &= ~CNL_COMP_PWR_DOWN;
        I915_WRITE(CHICKEN_MISC_2, val);
 
-       cnl_set_procmon_ref_values(dev_priv);
+       /* Dummy PORT_A to get the correct CNL register from the ICL macro */
+       cnl_set_procmon_ref_values(dev_priv, PORT_A);
 
        val = I915_READ(CNL_PORT_COMP_DW0);
        val |= COMP_INIT;
@@ -2911,6 +2961,80 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
        I915_WRITE(CHICKEN_MISC_2, val);
 }
 
+static void icl_display_core_init(struct drm_i915_private *dev_priv,
+                                 bool resume)
+{
+       enum port port;
+       u32 val;
+
+       gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+       /* 1. Enable PCH reset handshake. */
+       val = I915_READ(HSW_NDE_RSTWRN_OPT);
+       val |= RESET_PCH_HANDSHAKE_ENABLE;
+       I915_WRITE(HSW_NDE_RSTWRN_OPT, val);
+
+       for (port = PORT_A; port <= PORT_B; port++) {
+               /* 2. Enable DDI combo PHY comp. */
+               val = I915_READ(ICL_PHY_MISC(port));
+               val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
+               I915_WRITE(ICL_PHY_MISC(port), val);
+
+               cnl_set_procmon_ref_values(dev_priv, port);
+
+               val = I915_READ(ICL_PORT_COMP_DW0(port));
+               val |= COMP_INIT;
+               I915_WRITE(ICL_PORT_COMP_DW0(port), val);
+
+               /* 3. Set power down enable. */
+               val = I915_READ(ICL_PORT_CL_DW5(port));
+               val |= CL_POWER_DOWN_ENABLE;
+               I915_WRITE(ICL_PORT_CL_DW5(port), val);
+       }
+
+       /* 4. Enable power well 1 (PG1) and aux IO power. */
+       /* FIXME: ICL power wells code not here yet. */
+
+       /* 5. Enable CDCLK. */
+       icl_init_cdclk(dev_priv);
+
+       /* 6. Enable DBUF. */
+       icl_dbuf_enable(dev_priv);
+
+       /* 7. Setup MBUS. */
+       icl_mbus_init(dev_priv);
+
+       /* 8. CHICKEN_DCPR_1 */
+       I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
+                                       CNL_DDI_CLOCK_REG_ACCESS_ON);
+}
+
+static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
+{
+       enum port port;
+       u32 val;
+
+       gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+
+       /* 1. Disable all display engine functions -> aready done */
+
+       /* 2. Disable DBUF */
+       icl_dbuf_disable(dev_priv);
+
+       /* 3. Disable CD clock */
+       icl_uninit_cdclk(dev_priv);
+
+       /* 4. Disable Power Well 1 (PG1) and Aux IO Power */
+       /* FIXME: ICL power wells code not here yet. */
+
+       /* 5. Disable Comp */
+       for (port = PORT_A; port <= PORT_B; port++) {
+               val = I915_READ(ICL_PHY_MISC(port));
+               val |= ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
+               I915_WRITE(ICL_PHY_MISC(port), val);
+       }
+}
+
 static void chv_phy_control_init(struct drm_i915_private *dev_priv)
 {
        struct i915_power_well *cmn_bc =
@@ -3043,7 +3167,9 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
 
        power_domains->initializing = true;
 
-       if (IS_CANNONLAKE(dev_priv)) {
+       if (IS_ICELAKE(dev_priv)) {
+               icl_display_core_init(dev_priv, resume);
+       } else if (IS_CANNONLAKE(dev_priv)) {
                cnl_display_core_init(dev_priv, resume);
        } else if (IS_GEN9_BC(dev_priv)) {
                skl_display_core_init(dev_priv, resume);
@@ -3084,7 +3210,9 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv)
        if (!i915_modparams.disable_power_well)
                intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
 
-       if (IS_CANNONLAKE(dev_priv))
+       if (IS_ICELAKE(dev_priv))
+               icl_display_core_uninit(dev_priv);
+       else if (IS_CANNONLAKE(dev_priv))
                cnl_display_core_uninit(dev_priv);
        else if (IS_GEN9_BC(dev_priv))
                skl_display_core_uninit(dev_priv);
@@ -3200,18 +3328,19 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv)
  * @dev_priv: i915 device instance
  *
  * This function grabs a device-level runtime pm reference if the device is
- * already in use and ensures that it is powered up.
+ * already in use and ensures that it is powered up. It is illegal to try
+ * and access the HW should intel_runtime_pm_get_if_in_use() report failure.
  *
  * Any runtime pm reference obtained by this function must have a symmetric
  * call to intel_runtime_pm_put() to release the reference again.
+ *
+ * Returns: True if the wakeref was acquired, or False otherwise.
  */
 bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
 {
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       struct device *kdev = &pdev->dev;
-
        if (IS_ENABLED(CONFIG_PM)) {
-               int ret = pm_runtime_get_if_in_use(kdev);
+               struct pci_dev *pdev = dev_priv->drm.pdev;
+               struct device *kdev = &pdev->dev;
 
                /*
                 * In cases runtime PM is disabled by the RPM core and we get
@@ -3219,9 +3348,7 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
                 * function, since the power state is undefined. This applies
                 * atm to the late/early system suspend/resume handlers.
                 */
-               WARN_ONCE(ret < 0,
-                         "pm_runtime_get_if_in_use() failed: %d\n", ret);
-               if (ret <= 0)
+               if (pm_runtime_get_if_in_use(kdev) <= 0)
                        return false;
        }
 
index 0bf97ed5fface97b4dc85a1ffca51e8dd1ec08a0..0c14d1c04cbd93023d26e296f8ded09b7029e7e0 100644 (file)
@@ -214,7 +214,7 @@ static bool
 intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
                                   struct intel_sdvo_connector *intel_sdvo_connector);
 
-/**
+/*
  * Writes the SDVOB or SDVOC with the given value, but always writes both
  * SDVOB and SDVOC to work around apparent hardware issues (according to
  * comments in the BIOS).
@@ -250,10 +250,10 @@ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val)
         * writing them only once doesn't appear to 'stick'.
         * The BIOS does this too. Yay, magic
         */
-       for (i = 0; i < 2; i++)
-       {
+       for (i = 0; i < 2; i++) {
                I915_WRITE(GEN3_SDVOB, bval);
                POSTING_READ(GEN3_SDVOB);
+
                I915_WRITE(GEN3_SDVOC, cval);
                POSTING_READ(GEN3_SDVOC);
        }
@@ -643,7 +643,7 @@ static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo)
                                    &targets, sizeof(targets));
 }
 
-/**
+/*
  * Return whether each input is trained.
  *
  * This function is making an assumption about the layout of the response,
@@ -1061,8 +1061,10 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
        return true;
 }
 
-/* Asks the sdvo controller for the preferred input mode given the output mode.
- * Unfortunately we have to set up the full output mode to do that. */
+/*
+ * Asks the sdvo controller for the preferred input mode given the output mode.
+ * Unfortunately we have to set up the full output mode to do that.
+ */
 static bool
 intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
                                    const struct drm_display_mode *mode,
@@ -1095,8 +1097,10 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config)
        unsigned dotclock = pipe_config->port_clock;
        struct dpll *clock = &pipe_config->dpll;
 
-       /* SDVO TV has fixed PLL values depend on its clock range,
-          this mirrors vbios setting. */
+       /*
+        * SDVO TV has fixed PLL values depend on its clock range,
+        * this mirrors vbios setting.
+        */
        if (dotclock >= 100000 && dotclock < 140500) {
                clock->p1 = 2;
                clock->p2 = 10;
@@ -1132,7 +1136,8 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
        if (HAS_PCH_SPLIT(to_i915(encoder->base.dev)))
                pipe_config->has_pch_encoder = true;
 
-       /* We need to construct preferred input timings based on our
+       /*
+        * We need to construct preferred input timings based on our
         * output timings.  To do that, we have to set the output
         * timings, even though this isn't really the right place in
         * the sequence to do it. Oh well.
@@ -1155,7 +1160,8 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
                                                           adjusted_mode);
        }
 
-       /* Make the CRTC code factor in the SDVO pixel multiplier.  The
+       /*
+        * Make the CRTC code factor in the SDVO pixel multiplier.  The
         * SDVO device will factor out the multiplier during mode_set.
         */
        pipe_config->pixel_multiplier =
@@ -1169,9 +1175,12 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
                pipe_config->has_audio = true;
 
        if (intel_sdvo_state->base.broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) {
-               /* See CEA-861-E - 5.1 Default Encoding Parameters */
-               /* FIXME: This bit is only valid when using TMDS encoding and 8
-                * bit per color mode. */
+               /*
+                * See CEA-861-E - 5.1 Default Encoding Parameters
+                *
+                * FIXME: This bit is only valid when using TMDS encoding and 8
+                * bit per color mode.
+                */
                if (pipe_config->has_hdmi_sink &&
                    drm_match_cea_mode(adjusted_mode) > 1)
                        pipe_config->limited_color_range = true;
@@ -1272,7 +1281,8 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
 
        intel_sdvo_update_props(intel_sdvo, sdvo_state);
 
-       /* First, set the input mapping for the first input to our controlled
+       /*
+        * First, set the input mapping for the first input to our controlled
         * output. This is only correct if we're a single-input device, in
         * which case the first input is the output from the appropriate SDVO
         * channel on the motherboard.  In a two-input device, the first input
@@ -1435,8 +1445,10 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
 
        ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
        if (!ret) {
-               /* Some sdvo encoders are not spec compliant and don't
-                * implement the mandatory get_timings function. */
+               /*
+                * Some sdvo encoders are not spec compliant and don't
+                * implement the mandatory get_timings function.
+                */
                DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
                pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS;
        } else {
@@ -1585,7 +1597,9 @@ static void intel_enable_sdvo(struct intel_encoder *encoder,
                intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
 
        success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
-       /* Warn if the device reported failure to sync.
+       /*
+        * Warn if the device reported failure to sync.
+        *
         * A lot of SDVO devices fail to notify of sync, but it's
         * a given it the status is a success, we succeeded.
         */
@@ -1672,8 +1686,10 @@ static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo)
        if (!I915_HAS_HOTPLUG(dev_priv))
                return 0;
 
-       /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
-        * on the line. */
+       /*
+        * HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
+        * on the line.
+        */
        if (IS_I945G(dev_priv) || IS_I945GM(dev_priv))
                return 0;
 
@@ -1957,7 +1973,8 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
                      connector->base.id, connector->name);
 
-       /* Read the list of supported input resolutions for the selected TV
+       /*
+        * Read the list of supported input resolutions for the selected TV
         * format.
         */
        format_map = 1 << conn_state->tv.mode;
@@ -2268,7 +2285,8 @@ intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)
        uint16_t mask = 0;
        unsigned int num_bits;
 
-       /* Make a mask of outputs less than or equal to our own priority in the
+       /*
+        * Make a mask of outputs less than or equal to our own priority in the
         * list.
         */
        switch (sdvo->controlled_output) {
@@ -2298,7 +2316,7 @@ intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)
        sdvo->ddc_bus = 1 << num_bits;
 }
 
-/**
+/*
  * Choose the appropriate DDC bus for control bus switch command for this
  * SDVO output based on the controlled output.
  *
@@ -2342,9 +2360,11 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
 
        sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);
 
-       /* With gmbus we should be able to drive sdvo i2c at 2MHz, but somehow
+       /*
+        * With gmbus we should be able to drive sdvo i2c at 2MHz, but somehow
         * our code totally fails once we start using gmbus. Hence fall back to
-        * bit banging for now. */
+        * bit banging for now.
+        */
        intel_gmbus_force_bit(sdvo->i2c, true);
 }
 
@@ -2379,7 +2399,8 @@ intel_sdvo_get_slave_addr(struct drm_i915_private *dev_priv,
        if (my_mapping->slave_addr)
                return my_mapping->slave_addr;
 
-       /* If the BIOS only described a different SDVO device, use the
+       /*
+        * If the BIOS only described a different SDVO device, use the
         * address that it isn't using.
         */
        if (other_mapping->slave_addr) {
@@ -2389,7 +2410,8 @@ intel_sdvo_get_slave_addr(struct drm_i915_private *dev_priv,
                        return 0x70;
        }
 
-       /* No SDVO device info is found for another DVO port,
+       /*
+        * No SDVO device info is found for another DVO port,
         * so use mapping assumption we had before BIOS parsing.
         */
        if (sdvo->port == PORT_B)
@@ -2490,7 +2512,8 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
        if (intel_sdvo_get_hotplug_support(intel_sdvo) &
                intel_sdvo_connector->output_flag) {
                intel_sdvo->hotplug_active |= intel_sdvo_connector->output_flag;
-               /* Some SDVO devices have one-shot hotplug interrupts.
+               /*
+                * Some SDVO devices have one-shot hotplug interrupts.
                 * Ensure that they get re-enabled when an interrupt happens.
                 */
                intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
@@ -2789,7 +2812,7 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
                to_intel_sdvo_connector_state(conn_state);
        uint16_t response, data_value[2];
 
-       /* when horizontal overscan is supported, Add the left/right  property */
+       /* when horizontal overscan is supported, Add the left/right property */
        if (enhancements.overscan_h) {
                if (!intel_sdvo_get_value(intel_sdvo,
                                          SDVO_CMD_GET_MAX_OVERSCAN_H,
@@ -3074,7 +3097,8 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
                goto err_output;
        }
 
-       /* Only enable the hotplug irq if we need it, to work around noisy
+       /*
+        * Only enable the hotplug irq if we need it, to work around noisy
         * hotplug lines.
         */
        if (intel_sdvo->hotplug_active) {
index 3be22c0fcfb5d3257a5b732194569c7ff192c8e8..e098e4b2c85c7bd3d4efc15317b63d93948cbef9 100644 (file)
@@ -1063,8 +1063,8 @@ intel_check_sprite_plane(struct intel_plane *plane,
        return 0;
 }
 
-int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
-                             struct drm_file *file_priv)
+int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
+                                   struct drm_file *file_priv)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_intel_sprite_colorkey *set = data;
@@ -1077,6 +1077,9 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
        /* ignore the pointless "none" flag */
        set->flags &= ~I915_SET_COLORKEY_NONE;
 
+       if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
+               return -EINVAL;
+
        /* Make sure we don't try to enable both src & dest simultaneously */
        if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
                return -EINVAL;
index b3dabc219e6a12ae04a1977723a581cc0c4c4bb3..885fc3809f7f904e8bc82e0eeee9cddd3dcef3f4 100644 (file)
@@ -43,7 +43,6 @@ enum tv_margin {
        TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
 };
 
-/** Private structure for the integrated TV support */
 struct intel_tv {
        struct intel_encoder base;
 
@@ -370,12 +369,11 @@ struct tv_mode {
  * The constants below were all computed using a 107.520MHz clock
  */
 
-/**
+/*
  * Register programming values for TV modes.
  *
  * These values account for -1s required.
  */
-
 static const struct tv_mode tv_modes[] = {
        {
                .name           = "NTSC-M",
@@ -1126,14 +1124,6 @@ static const struct drm_display_mode reported_modes[] = {
        },
 };
 
-/**
- * Detects TV presence by checking for load.
- *
- * Requires that the current pipe's DPLL is active.
-
- * \return true if TV is connected.
- * \return false if TV is disconnected.
- */
 static int
 intel_tv_detect_type(struct intel_tv *intel_tv,
                      struct drm_connector *connector)
@@ -1259,12 +1249,6 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
        connector->state->tv.mode = i;
 }
 
-/**
- * Detect the TV connection.
- *
- * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
- * we have a pipe programmed in order to probe the TV.
- */
 static int
 intel_tv_detect(struct drm_connector *connector,
                struct drm_modeset_acquire_ctx *ctx,
@@ -1339,13 +1323,6 @@ intel_tv_choose_preferred_modes(const struct tv_mode *tv_mode,
        }
 }
 
-/**
- * Stub get_modes function.
- *
- * This should probably return a set of fixed modes, unless we can figure out
- * how to probe modes off of TV connections.
- */
-
 static int
 intel_tv_get_modes(struct drm_connector *connector)
 {
@@ -1512,7 +1489,8 @@ intel_tv_init(struct drm_i915_private *dev_priv)
        connector = &intel_connector->base;
        state = connector->state;
 
-       /* The documentation, for the older chipsets at least, recommend
+       /*
+        * The documentation, for the older chipsets at least, recommend
         * using a polling method rather than hotplug detection for TVs.
         * This is because in order to perform the hotplug detection, the PLLs
         * for the TV must be kept alive increasing power drain and starving
index 784eff9cdfc891242459116bf4b4514868992c78..3ec0ce505b76f86a0f3f0541a3ef9a1e393a27bf 100644 (file)
@@ -197,11 +197,12 @@ fail:
 
 /**
  * intel_uc_fw_upload - load uC firmware using custom loader
- *
  * @uc_fw: uC firmware
- * @loader: custom uC firmware loader function
+ * @xfer: custom uC firmware loader function
  *
  * Loads uC firmware using custom loader and updates internal flags.
+ *
+ * Return: 0 on success, non-zero on failure.
  */
 int intel_uc_fw_upload(struct intel_uc_fw *uc_fw,
                       int (*xfer)(struct intel_uc_fw *uc_fw,
index 164dbb8cfa3682385986447c853997301a4b9f02..5ae9a62712cad81c69ad98c2b8ff2d8b36667140 100644 (file)
@@ -1522,9 +1522,11 @@ static void gen3_stop_engine(struct intel_engine_cs *engine)
                                 engine->name);
 
        I915_WRITE_FW(RING_HEAD(base), I915_READ_FW(RING_TAIL(base)));
+       POSTING_READ_FW(RING_HEAD(base)); /* paranoia */
 
        I915_WRITE_FW(RING_HEAD(base), 0);
        I915_WRITE_FW(RING_TAIL(base), 0);
+       POSTING_READ_FW(RING_TAIL(base));
 
        /* The ring must be empty before it is disabled */
        I915_WRITE_FW(RING_CTL(base), 0);
@@ -1548,24 +1550,31 @@ static void i915_stop_engines(struct drm_i915_private *dev_priv,
                gen3_stop_engine(engine);
 }
 
-static bool i915_reset_complete(struct pci_dev *pdev)
+static bool i915_in_reset(struct pci_dev *pdev)
 {
        u8 gdrst;
 
        pci_read_config_byte(pdev, I915_GDRST, &gdrst);
-       return (gdrst & GRDOM_RESET_STATUS) == 0;
+       return gdrst & GRDOM_RESET_STATUS;
 }
 
 static int i915_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask)
 {
        struct pci_dev *pdev = dev_priv->drm.pdev;
+       int err;
 
-       /* assert reset for at least 20 usec */
+       /* Assert reset for at least 20 usec, and wait for acknowledgement. */
        pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE);
        usleep_range(50, 200);
+       err = wait_for(i915_in_reset(pdev), 500);
+
+       /* Clear the reset request. */
        pci_write_config_byte(pdev, I915_GDRST, 0);
+       usleep_range(50, 200);
+       if (!err)
+               err = wait_for(!i915_in_reset(pdev), 500);
 
-       return wait_for(i915_reset_complete(pdev), 500);
+       return err;
 }
 
 static bool g4x_reset_complete(struct pci_dev *pdev)
@@ -1874,9 +1883,9 @@ static reset_func intel_get_gpu_reset(struct drm_i915_private *dev_priv)
        if (!i915_modparams.reset)
                return NULL;
 
-       if (INTEL_INFO(dev_priv)->gen >= 8)
+       if (INTEL_GEN(dev_priv) >= 8)
                return gen8_reset_engines;
-       else if (INTEL_INFO(dev_priv)->gen >= 6)
+       else if (INTEL_GEN(dev_priv) >= 6)
                return gen6_reset_engines;
        else if (IS_GEN5(dev_priv))
                return ironlake_do_reset;
@@ -1884,7 +1893,7 @@ static reset_func intel_get_gpu_reset(struct drm_i915_private *dev_priv)
                return g4x_do_reset;
        else if (IS_G33(dev_priv) || IS_PINEVIEW(dev_priv))
                return g33_do_reset;
-       else if (INTEL_INFO(dev_priv)->gen >= 3)
+       else if (INTEL_GEN(dev_priv) >= 3)
                return i915_do_reset;
        else
                return NULL;
index bed019ef000fa6677c22e58711e6be23d6164645..53ef77d0c97c55bf89afd286e4b27034a13c7ae6 100644 (file)
@@ -198,4 +198,9 @@ int intel_wait_for_register_fw(struct drm_i915_private *dev_priv,
                                            2, timeout_ms, NULL);
 }
 
+#define raw_reg_read(base, reg) \
+       readl(base + i915_mmio_reg_offset(reg))
+#define raw_reg_write(base, reg, value) \
+       writel(value, base + i915_mmio_reg_offset(reg))
+
 #endif /* !__INTEL_UNCORE_H__ */
index a2632df3917353b246a1316f3322811476c24418..391f3d9ffdf1ab652530121cb6d439b987039a8a 100644 (file)
@@ -129,8 +129,8 @@ huge_gem_object(struct drm_i915_private *i915,
        drm_gem_private_object_init(&i915->drm, &obj->base, dma_size);
        i915_gem_object_init(obj, &huge_ops);
 
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU;
-       obj->base.write_domain = I915_GEM_DOMAIN_CPU;
+       obj->read_domains = I915_GEM_DOMAIN_CPU;
+       obj->write_domain = I915_GEM_DOMAIN_CPU;
        cache_level = HAS_LLC(i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
        i915_gem_object_set_cache_coherency(obj, cache_level);
        obj->scratch = phys_size;
index 2ea69394f42839f8ede1cc9475cd9ee9c16ba983..52b1bd17bf46c105ce15bf589b0b7b6e16eaaede 100644 (file)
@@ -178,8 +178,8 @@ huge_pages_object(struct drm_i915_private *i915,
        drm_gem_private_object_init(&i915->drm, &obj->base, size);
        i915_gem_object_init(obj, &huge_page_ops);
 
-       obj->base.write_domain = I915_GEM_DOMAIN_CPU;
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+       obj->write_domain = I915_GEM_DOMAIN_CPU;
+       obj->read_domains = I915_GEM_DOMAIN_CPU;
        obj->cache_level = I915_CACHE_NONE;
 
        obj->mm.page_mask = page_mask;
@@ -329,8 +329,8 @@ fake_huge_pages_object(struct drm_i915_private *i915, u64 size, bool single)
        else
                i915_gem_object_init(obj, &fake_ops);
 
-       obj->base.write_domain = I915_GEM_DOMAIN_CPU;
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+       obj->write_domain = I915_GEM_DOMAIN_CPU;
+       obj->read_domains = I915_GEM_DOMAIN_CPU;
        obj->cache_level = I915_CACHE_NONE;
 
        return obj;
index 56a803d11916e8142d04623876a81d48d03b1a25..6da2a2f29c5483cb8829d800012b0836428a0f3f 100644 (file)
@@ -215,8 +215,8 @@ static int cpu_fill(struct drm_i915_gem_object *obj, u32 value)
        }
 
        i915_gem_obj_finish_shmem_access(obj);
-       obj->base.read_domains = I915_GEM_DOMAIN_GTT | I915_GEM_DOMAIN_CPU;
-       obj->base.write_domain = 0;
+       obj->read_domains = I915_GEM_DOMAIN_GTT | I915_GEM_DOMAIN_CPU;
+       obj->write_domain = 0;
        return 0;
 }
 
index d8064276431cf5ab60bf406bd87d1f1f407a4bab..f7dc926f4ef1fa610e5415d0b2771b30fcbdbbe5 100644 (file)
@@ -113,8 +113,8 @@ fake_dma_object(struct drm_i915_private *i915, u64 size)
        drm_gem_private_object_init(&i915->drm, &obj->base, size);
        i915_gem_object_init(obj, &fake_ops);
 
-       obj->base.write_domain = I915_GEM_DOMAIN_CPU;
-       obj->base.read_domains = I915_GEM_DOMAIN_CPU;
+       obj->write_domain = I915_GEM_DOMAIN_CPU;
+       obj->read_domains = I915_GEM_DOMAIN_CPU;
        obj->cache_level = I915_CACHE_NONE;
 
        /* Preallocate the "backing storage" */
@@ -927,7 +927,7 @@ static int shrink_boom(struct drm_i915_private *i915,
 
                explode = fake_dma_object(i915, size);
                if (IS_ERR(explode)) {
-                       err = PTR_ERR(purge);
+                       err = PTR_ERR(explode);
                        goto err_purge;
                }
 
index f32aa6bb79e294e004a989ab0a9d3c8fda2a2c25..3c64815e910b3145c0e9f51f3152c8a33fc9e698 100644 (file)
@@ -212,8 +212,11 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj,
                return -EINTR;
 
        err = i915_gem_object_set_tiling(obj, tile->tiling, tile->stride);
-       if (err)
+       if (err) {
+               pr_err("Failed to set tiling mode=%u, stride=%u, err=%d\n",
+                      tile->tiling, tile->stride, err);
                return err;
+       }
 
        GEM_BUG_ON(i915_gem_object_get_tiling(obj) != tile->tiling);
        GEM_BUG_ON(i915_gem_object_get_stride(obj) != tile->stride);
@@ -230,13 +233,16 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj,
                GEM_BUG_ON(view.partial.size > nreal);
 
                err = i915_gem_object_set_to_gtt_domain(obj, true);
-               if (err)
+               if (err) {
+                       pr_err("Failed to flush to GTT write domain; err=%d\n",
+                              err);
                        return err;
+               }
 
                vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
                if (IS_ERR(vma)) {
-                       pr_err("Failed to pin partial view: offset=%lu\n",
-                              page);
+                       pr_err("Failed to pin partial view: offset=%lu; err=%d\n",
+                              page, (int)PTR_ERR(vma));
                        return PTR_ERR(vma);
                }
 
@@ -246,8 +252,8 @@ static int check_partial_mapping(struct drm_i915_gem_object *obj,
                io = i915_vma_pin_iomap(vma);
                i915_vma_unpin(vma);
                if (IS_ERR(io)) {
-                       pr_err("Failed to iomap partial view: offset=%lu\n",
-                              page);
+                       pr_err("Failed to iomap partial view: offset=%lu; err=%d\n",
+                              page, (int)PTR_ERR(io));
                        return PTR_ERR(io);
                }
 
index 3f9016466deaf74ebfb64587a5f6006a5202c249..fb74e2cf8a0a9a56d28974d04a23f42cc92bfcb1 100644 (file)
@@ -87,7 +87,7 @@ static int validate_client(struct intel_guc_client *client,
 
 static bool client_doorbell_in_sync(struct intel_guc_client *client)
 {
-       return doorbell_ok(client->guc, client->doorbell_id);
+       return !client || doorbell_ok(client->guc, client->doorbell_id);
 }
 
 /*
@@ -137,7 +137,6 @@ static int igt_guc_clients(void *args)
                goto unlock;
        }
        GEM_BUG_ON(!guc->execbuf_client);
-       GEM_BUG_ON(!guc->preempt_client);
 
        err = validate_client(guc->execbuf_client,
                              GUC_CLIENT_PRIORITY_KMD_NORMAL, false);
@@ -146,16 +145,18 @@ static int igt_guc_clients(void *args)
                goto out;
        }
 
-       err = validate_client(guc->preempt_client,
-                             GUC_CLIENT_PRIORITY_KMD_HIGH, true);
-       if (err) {
-               pr_err("preempt client validation failed\n");
-               goto out;
+       if (guc->preempt_client) {
+               err = validate_client(guc->preempt_client,
+                                     GUC_CLIENT_PRIORITY_KMD_HIGH, true);
+               if (err) {
+                       pr_err("preempt client validation failed\n");
+                       goto out;
+               }
        }
 
        /* each client should now have reserved a doorbell */
        if (!has_doorbell(guc->execbuf_client) ||
-           !has_doorbell(guc->preempt_client)) {
+           (guc->preempt_client && !has_doorbell(guc->preempt_client))) {
                pr_err("guc_clients_create didn't reserve doorbells\n");
                err = -EINVAL;
                goto out;
@@ -224,7 +225,8 @@ out:
         * clients during unload.
         */
        destroy_doorbell(guc->execbuf_client);
-       destroy_doorbell(guc->preempt_client);
+       if (guc->preempt_client)
+               destroy_doorbell(guc->preempt_client);
        guc_clients_destroy(guc);
        guc_clients_create(guc);
        guc_clients_doorbell_init(guc);
index 1bc61f3f76fce003364eb86625cff6704e9443a1..3175db70cc6e0ce14badf19ea481cf3032dd3057 100644 (file)
@@ -243,16 +243,10 @@ struct drm_i915_private *mock_gem_device(void)
        if (!i915->kernel_context)
                goto err_engine;
 
-       i915->preempt_context = mock_context(i915, NULL);
-       if (!i915->preempt_context)
-               goto err_kernel_context;
-
        WARN_ON(i915_gemfs_init(i915));
 
        return i915;
 
-err_kernel_context:
-       i915_gem_context_put(i915->kernel_context);
 err_engine:
        for_each_engine(engine, i915, id)
                mock_engine_free(engine);
index dfda5e0ed1660d3d91344749aae48fd39a229dc4..26129b2b082dfb3f0e4743c6e56ddad40c4737be 100644 (file)
@@ -570,7 +570,7 @@ static int radeon_crtc_page_flip_target(struct drm_crtc *crtc,
                base &= ~7;
        }
        work->base = base;
-       work->target_vblank = target - drm_crtc_vblank_count(crtc) +
+       work->target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) +
                dev->driver->get_vblank_counter(dev, work->crtc_id);
 
        /* We borrow the event spin lock for protecting flip_work */
index b8403ed48285288c277d224e253285caebed3adb..49df2db2ad4648fccdc4f3d8d4609fdae3aa5ebe 100644 (file)
@@ -1359,7 +1359,7 @@ static u32 tegra_dc_get_vblank_counter(struct drm_crtc *crtc)
                return host1x_syncpt_read(dc->syncpt);
 
        /* fallback to software emulated VBLANK counter */
-       return drm_crtc_vblank_count(&dc->base);
+       return (u32)drm_crtc_vblank_count(&dc->base);
 }
 
 static int tegra_dc_enable_vblank(struct drm_crtc *crtc)
index cf13842a6dbd1fa8808f4e9c0d49a5f9b012c931..2c711a24c80cfcc01baae9dc8e17eeeafa55a152 100644 (file)
@@ -154,7 +154,7 @@ struct __drm_crtcs_state {
        struct drm_crtc *ptr;
        struct drm_crtc_state *state, *old_state, *new_state;
        s32 __user *out_fence_ptr;
-       unsigned last_vblank_count;
+       u64 last_vblank_count;
 };
 
 struct __drm_connnectors_state {
index 9c55c2acaa2b366dc5b93f068f66575aa3177a64..3583b98a1718139eb07dbda254af71987a45602b 100644 (file)
@@ -115,21 +115,6 @@ struct drm_gem_object {
         */
        int name;
 
-       /**
-        * @read_domains:
-        *
-        * Read memory domains. These monitor which caches contain read/write data
-        * related to the object. When transitioning from one set of domains
-        * to another, the driver is called to ensure that caches are suitably
-        * flushed and invalidated.
-        */
-       uint32_t read_domains;
-
-       /**
-        * @write_domain: Corresponding unique write memory domain.
-        */
-       uint32_t write_domain;
-
        /**
         * @dma_buf:
         *
index 425ad80ed2ac03783a2603cf9cd8205628872498..d25a9603ab570518eb38945a920f459dae343397 100644 (file)
@@ -195,7 +195,9 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
 void drm_crtc_vblank_off(struct drm_crtc *crtc);
 void drm_crtc_vblank_reset(struct drm_crtc *crtc);
 void drm_crtc_vblank_on(struct drm_crtc *crtc);
-u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
+u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
+void drm_vblank_restore(struct drm_device *dev, unsigned int pipe);
+void drm_crtc_vblank_restore(struct drm_crtc *crtc);
 
 bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
                                           unsigned int pipe, int *max_error,
index 9e1fe6634424203e66d9393b17c6456d9f289777..0b2ba46fa00b56f666d505941752ed0ccb21c0cb 100644 (file)
 
 /* CNL */
 #define INTEL_CNL_IDS(info) \
-       INTEL_VGA_DEVICE(0x5A52, info), \
-       INTEL_VGA_DEVICE(0x5A5A, info), \
-       INTEL_VGA_DEVICE(0x5A42, info), \
-       INTEL_VGA_DEVICE(0x5A4A, info), \
        INTEL_VGA_DEVICE(0x5A51, info), \
        INTEL_VGA_DEVICE(0x5A59, info), \
        INTEL_VGA_DEVICE(0x5A41, info), \
        INTEL_VGA_DEVICE(0x5A49, info), \
-       INTEL_VGA_DEVICE(0x5A71, info), \
-       INTEL_VGA_DEVICE(0x5A79, info), \
+       INTEL_VGA_DEVICE(0x5A52, info), \
+       INTEL_VGA_DEVICE(0x5A5A, info), \
+       INTEL_VGA_DEVICE(0x5A42, info), \
+       INTEL_VGA_DEVICE(0x5A4A, info), \
+       INTEL_VGA_DEVICE(0x5A50, info), \
+       INTEL_VGA_DEVICE(0x5A40, info), \
        INTEL_VGA_DEVICE(0x5A54, info), \
        INTEL_VGA_DEVICE(0x5A5C, info), \
-       INTEL_VGA_DEVICE(0x5A44, info)
+       INTEL_VGA_DEVICE(0x5A44, info), \
+       INTEL_VGA_DEVICE(0x5A4C, info)
 
 #endif /* _I915_PCIIDS_H */