From 91df09d92ad82c8778ca218097bf827f154292ca Mon Sep 17 00:00:00 2001 From: Mika Kahola Date: Mon, 20 Jun 2016 11:10:26 +0300 Subject: drm/i915: Revert DisplayPort fast link training feature It has been found out that in some HW combination the DisplayPort fast link training feature caused screen flickering. Let's revert this feature for now until we can ensure that the feature works for all platforms. This is a manual revert of commits 5fa836a9d859 ("drm/i915: DP link training optimization") and 4e96c97742f4 ("drm/i915: eDP link training optimization"). Fixes: 5fa836a9d859 ("drm/i915: DP link training optimization") Fixes: 4e96c97742f4 ("drm/i915: eDP link training optimization") Cc: # v4.2+ Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91393 Reviewed-by: Jani Nikula Signed-off-by: Mika Kahola Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1466410226-19543-1-git-send-email-mika.kahola@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 3 --- drivers/gpu/drm/i915/intel_dp_link_training.c | 26 ++------------------------ drivers/gpu/drm/i915/intel_drv.h | 2 -- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index be083519dac9..3cdea4d7a917 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4621,9 +4621,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) intel_display_power_get(dev_priv, power_domain); if (long_hpd) { - /* indicate that we need to restart link training */ - intel_dp->train_set_valid = false; - intel_dp_long_pulse(intel_dp->attached_connector); if (intel_dp->is_mst) ret = IRQ_HANDLED; diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index 0b8eefc2acc5..60fb39cd220b 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c @@ -85,8 +85,7 @@ static bool intel_dp_reset_link_train(struct intel_dp *intel_dp, uint8_t dp_train_pat) { - if (!intel_dp->train_set_valid) - memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); + memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); intel_dp_set_signal_levels(intel_dp); return intel_dp_set_link_train(intel_dp, dp_train_pat); } @@ -161,23 +160,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) break; } - /* - * if we used previously trained voltage and pre-emphasis values - * and we don't get clock recovery, reset link training values - */ - if (intel_dp->train_set_valid) { - DRM_DEBUG_KMS("clock recovery not ok, reset"); - /* clear the flag as we are not reusing train set */ - intel_dp->train_set_valid = false; - if (!intel_dp_reset_link_train(intel_dp, - DP_TRAINING_PATTERN_1 | - DP_LINK_SCRAMBLING_DISABLE)) { - DRM_ERROR("failed to enable link training\n"); - return; - } - continue; - } - /* Check to see if we've tried the max voltage */ for (i = 0; i < intel_dp->lane_count; i++) if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) @@ -284,7 +266,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) /* Make sure clock is still ok */ if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { - intel_dp->train_set_valid = false; intel_dp_link_training_clock_recovery(intel_dp); intel_dp_set_link_train(intel_dp, training_pattern | @@ -301,7 +282,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) /* Try 5 times, then try clock recovery if that fails */ if (tries > 5) { - intel_dp->train_set_valid = false; intel_dp_link_training_clock_recovery(intel_dp); intel_dp_set_link_train(intel_dp, training_pattern | @@ -322,10 +302,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) intel_dp_set_idle_link_train(intel_dp); - if (channel_eq) { - intel_dp->train_set_valid = true; + if (channel_eq) DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); - } } void intel_dp_stop_link_train(struct intel_dp *intel_dp) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0c1dc9bae170..9257f08aa677 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -894,8 +894,6 @@ struct intel_dp { /* This is called before a link training is starterd */ void (*prepare_link_retrain)(struct intel_dp *intel_dp); - bool train_set_valid; - /* Displayport compliance testing */ unsigned long compliance_test_type; unsigned long compliance_test_data; -- cgit v1.2.3 From b9bcd14a2b91be73d694b3e809d54a287232839e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 20 Jun 2016 15:05:51 +0100 Subject: drm/i915: Extract checking for backing struct pages to a helper Currently to see if an object is backed by struct pages (as opposed to being a simple pointer to stolen memory, for example) we do a manual check on the obj->ops->flags. This is quite shouty and before adding more checks in future, we should make it a bit calmer. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1466431552-17860-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ drivers/gpu/drm/i915/i915_gem.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index de4bf367c66c..0fcf4e41f6da 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2266,6 +2266,12 @@ struct drm_i915_gem_object { }; #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) +static inline bool +i915_gem_object_has_struct_page(const struct drm_i915_gem_object *obj) +{ + return obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE; +} + /* * Optimised SGL iterator for GEM objects */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 21d0dea57312..7f6879cc82fb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -508,7 +508,7 @@ int i915_gem_obj_prepare_shmem_read(struct drm_i915_gem_object *obj, *needs_clflush = 0; - if (WARN_ON((obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE) == 0)) + if (WARN_ON(!i915_gem_object_has_struct_page(obj))) return -EINVAL; if (!(obj->base.read_domains & I915_GEM_DOMAIN_CPU)) { @@ -5528,7 +5528,7 @@ i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, int n) struct page *page; /* Only default objects have per-page dirty tracking */ - if (WARN_ON((obj->ops->flags & I915_GEM_OBJECT_HAS_STRUCT_PAGE) == 0)) + if (WARN_ON(!i915_gem_object_has_struct_page(obj))) return NULL; page = i915_gem_object_get_page(obj, n); -- cgit v1.2.3 From 6eae0059f9a4513c8dd3e3e08c1f65727d22fff7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 20 Jun 2016 15:05:52 +0100 Subject: drm/i915: pwrite/pread do not require obj->base.filp, just pages The idea behind relaxing the restriction for pread/pwrite was to handle !obj->base.flip, i.e. non-shmemfs backed objects, which only requires that the object provide struct pages. v2: Remove excess (). Note enough editing after copy'n'paste. v3: Use new i915_gem_object_has_struct_page() Testcase: igt/prime_vgem/read Signed-off-by: Chris Wilson Cc: Ankitprasad Sharma Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1466431552-17860-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7f6879cc82fb..604989b81131 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -760,7 +760,7 @@ i915_gem_shmem_pread(struct drm_device *dev, int needs_clflush = 0; struct sg_page_iter sg_iter; - if (!obj->base.filp) + if (!i915_gem_object_has_struct_page(obj)) return -ENODEV; user_data = u64_to_user_ptr(args->data_ptr); @@ -1298,7 +1298,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * pread/pwrite currently are reading and writing from the CPU * perspective, requiring manual detiling by the client. */ - if (!obj->base.filp || cpu_write_needs_clflush(obj)) { + if (!i915_gem_object_has_struct_page(obj) || + cpu_write_needs_clflush(obj)) { ret = i915_gem_gtt_pwrite_fast(dev_priv, obj, args, file); /* Note that the gtt paths might fail with non-page-backed user * pointers (e.g. gtt mappings when moving data between @@ -1308,7 +1309,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, if (ret == -EFAULT) { if (obj->phys_handle) ret = i915_gem_phys_pwrite(obj, args, file); - else if (obj->base.filp) + else if (i915_gem_object_has_struct_page(obj)) ret = i915_gem_shmem_pwrite(dev, obj, args, file); else ret = -ENODEV; -- cgit v1.2.3 From c7f7e2feffb0294302041507dfd5fc15f01afccc Mon Sep 17 00:00:00 2001 From: Lyude Date: Thu, 9 Jun 2016 11:58:15 -0400 Subject: drm/i915/fbc: Disable on HSW by default for now >From https://bugs.freedesktop.org/show_bug.cgi?id=96461 : This was kind of a difficult bug to track down. If you're using a Haswell system running GNOME and you have fbc completely enabled and working, playing videos can result in video artifacts. Steps to reproduce: - Run GNOME - Ensure FBC is enabled and active - Download a movie, I used the ogg version of Big Buck Bunny for this - Run `gst-launch-1.0 filesrc location='some_movie.ogg' ! decodebin ! glimagesink` in a terminal - Watch for about over a minute, you'll see small horizontal lines go down the screen. For the time being, disable FBC for Haswell by default. Stefan Richter reported kernel freezes (no video artifacts) when fbc is on. (E3-1245 v3 with HD P4600; openbox and some KDE and LXDE applications, thread begins at https://lkml.org/lkml/2016/4/26/813). We also got reports from Steven Honeyman on openbox+roxterm. v2 (From Paulo): - Add extra information to the commit message - Add Fixes tag - Rebase Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96461 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96464 Fixes: a98ee79317b4 ("drm/i915/fbc: enable FBC by default on HSW and BDW") Cc: stable@vger.kernel.org Reviewed-by: Paulo Zanoni Signed-off-by: Lyude Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1465487895-7401-1-git-send-email-cpaul@redhat.com --- drivers/gpu/drm/i915/intel_fbc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index ecabd59ffbaf..a19944b6dc25 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -818,8 +818,7 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; - bool enable_by_default = IS_HASWELL(dev_priv) || - IS_BROADWELL(dev_priv); + bool enable_by_default = IS_BROADWELL(dev_priv); if (intel_vgpu_active(dev_priv)) { fbc->no_fbc_reason = "VGPU is active"; -- cgit v1.2.3 From ab28a5474a497d201091ba20ca9c33260bb2b2af Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 4 Apr 2016 18:17:15 -0300 Subject: drm/i915/fbc: update busy_bits even for GTT and flip flushes We ignore ORIGIN_GTT because the hardware tracking can recognize GTT writes and take care of them. We also ignore ORIGIN_FLIP because we deal with flips without relying on the frontbuffer tracking infrastructure. On the other hand, a flush is a flush and means we're good to go, so we need to update busy_bits in order to reflect that, even if we're not going to do anything else about it. How to reproduce the bug fixed by this patch: - boot SKL up to the desktop environment - stop the display manager - run any of the igt/kms_frontbuffer_tracking/*fbc*onoff* subtests - the tests will fail The steps above will create the right conditions for us to lose track of busy_bits. If you, for example, run the full set of FBC tests, the onoff subtests will succeed. Also notice that the "bug" is that we'll just keep FBC disabled on cases where it could be enabled, so it's not something the users can perceive, it just affects power consumption numbers on properly configured machines. Testcase: igt/kms_frontbuffer_tracking/*fbc*onoff* (see above) Reviewed-by: Daniel Vetter Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1459804638-3588-2-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index a19944b6dc25..e43c867490e5 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -992,13 +992,13 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, if (!fbc_supported(dev_priv)) return; - if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) - return; - mutex_lock(&fbc->lock); fbc->busy_bits &= ~frontbuffer_bits; + if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP) + goto out; + if (!fbc->busy_bits && fbc->enabled && (frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) { if (fbc->active) @@ -1007,6 +1007,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv, __intel_fbc_post_update(fbc->crtc); } +out: mutex_unlock(&fbc->lock); } -- cgit v1.2.3 From 80788a0fbbdfbb125e3fd45a640cddb582160bc7 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 13 Apr 2016 16:01:09 -0300 Subject: drm/i915/fbc: sanitize i915.enable_fbc during FBC init The DDX driver changes its behavior depending on the value it reads from i915.enable_fbc, so sanitize the value in order to allow it to know what's going on. It uses this in order to choose the defaults for the TearFree option. Before this patch, it would read -1 and always assume that FBC was disabled, so it wouldn't force TearFree. v2: Extract intel_sanitize_fbc_option() (Chris). v3: Rebase. Signed-off-by: Paulo Zanoni Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1460574069-14005-1-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/intel_fbc.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index e43c867490e5..97110533dcaa 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -818,20 +818,14 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; struct intel_fbc *fbc = &dev_priv->fbc; - bool enable_by_default = IS_BROADWELL(dev_priv); if (intel_vgpu_active(dev_priv)) { fbc->no_fbc_reason = "VGPU is active"; return false; } - if (i915.enable_fbc < 0 && !enable_by_default) { - fbc->no_fbc_reason = "disabled per chip default"; - return false; - } - if (!i915.enable_fbc) { - fbc->no_fbc_reason = "disabled per module param"; + fbc->no_fbc_reason = "disabled per module param or by default"; return false; } @@ -1220,6 +1214,26 @@ void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv) dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe); } +/* + * The DDX driver changes its behavior depending on the value it reads from + * i915.enable_fbc, so sanitize it by translating the default value into either + * 0 or 1 in order to allow it to know what's going on. + * + * Notice that this is done at driver initialization and we still allow user + * space to change the value during runtime without sanitizing it again. IGT + * relies on being able to change i915.enable_fbc at runtime. + */ +static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv) +{ + if (i915.enable_fbc >= 0) + return !!i915.enable_fbc; + + if (IS_BROADWELL(dev_priv)) + return 1; + + return 0; +} + /** * intel_fbc_init - Initialize FBC * @dev_priv: the i915 device @@ -1237,6 +1251,9 @@ void intel_fbc_init(struct drm_i915_private *dev_priv) fbc->active = false; fbc->work.scheduled = false; + i915.enable_fbc = intel_sanitize_fbc_option(dev_priv); + DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n", i915.enable_fbc); + if (!HAS_FBC(dev_priv)) { fbc->no_fbc_reason = "unsupported by this chipset"; return; -- cgit v1.2.3 From aeecc9696aa04a82d629e7276134bd54b2afc9e2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Jun 2016 14:46:39 -0300 Subject: drm/i915: use ORIGIN_CPU for frontbuffer invalidation on WC mmaps ... instead of the previous ORIGIN_GTT. This should actually invalidate FBC once something is written on the frontbuffer using WC mmaps. The problem with ORIGIN_GTT is that the automatic hardware tracking is not able to detect the WC writes as it can detect the GTT writes. This should help fix the SKL bug where nothing happens when you type your username/password on lightdm. This patch was originally pasted on an email by Chris and converted to an actual git patch by Paulo. v2 (from Paulo): - Make it a full variable instead of a bit-field (Daniel) - Use WRITE_ONCE (Chris) v3 (from Paulo): - Remove huge comment since now we have WRITE_ONCE (Chris) - Remove uneeded new line (Chris) - Add Chris' Signed-off-by, authorized via IRC Cc: Chris Wilson Reviewed-by: Daniel Vetter Signed-off-by: Chris Wilson Signed-off-by: Paulo Zanoni Link: http://patchwork.freedesktop.org/patch/msgid/1466185599-26401-1-git-send-email-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0fcf4e41f6da..9e09d91d4c7a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2214,6 +2214,7 @@ struct drm_i915_gem_object { unsigned int frontbuffer_bits:INTEL_FRONTBUFFER_BITS; + unsigned int has_wc_mmap; unsigned int pin_display; struct sg_table *pages; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 604989b81131..6abd5e590373 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1810,6 +1810,13 @@ static struct intel_rps_client *to_rps_client(struct drm_file *file) return &fpriv->rps; } +static enum fb_op_origin +write_origin(struct drm_i915_gem_object *obj, unsigned domain) +{ + return domain == I915_GEM_DOMAIN_GTT && !obj->has_wc_mmap ? + ORIGIN_GTT : ORIGIN_CPU; +} + /** * Called when user space prepares to use an object with the CPU, either * through the mmap ioctl's mapping or a GTT mapping. @@ -1866,9 +1873,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); if (write_domain != 0) - intel_fb_obj_invalidate(obj, - write_domain == I915_GEM_DOMAIN_GTT ? - ORIGIN_GTT : ORIGIN_CPU); + intel_fb_obj_invalidate(obj, write_origin(obj, write_domain)); unref: drm_gem_object_unreference(&obj->base); @@ -1975,6 +1980,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, else addr = -ENOMEM; up_write(&mm->mmap_sem); + + /* This may race, but that's ok, it only gets set */ + WRITE_ONCE(to_intel_bo(obj)->has_wc_mmap, true); } drm_gem_object_unreference_unlocked(obj); if (IS_ERR((void *)addr)) -- cgit v1.2.3 From d626f34573551479f62b09d4df09efc4af88136d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Jun 2016 09:16:53 +0100 Subject: drm/i915/fbdev: Perform async fbdev initialisation much later Setting up fbdev requires everything ready and registered (in particular the connectors). In the forthcoming patches, we defer registration of the KMS objects and unless we defer setting off fbdev, it may run before they are registered and oops. Signed-off-by: Chris Wilson Cc: Daniel Vetter Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466497015-8509-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_dma.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d15a461fa84a..e28c0ddc0837 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -525,18 +525,6 @@ static int i915_load_modeset_init(struct drm_device *dev) /* Only enable hotplug handling once the fbdev is fully set up. */ intel_hpd_init(dev_priv); - /* - * Some ports require correctly set-up hpd registers for detection to - * work properly (leading to ghost connected connector status), e.g. VGA - * on gm45. Hence we can only set up the initial fbdev config after hpd - * irqs are fully enabled. Now we should scan for the initial config - * only once hotplug handling is enabled, but due to screwed-up locking - * around kms/fbdev init we can't protect the fdbev initial config - * scanning against hotplug events. Hence do this first and ignore the - * tiny window where we will loose hotplug notifactions. - */ - intel_fbdev_initial_config_async(dev); - drm_kms_helper_poll_init(dev); return 0; @@ -1421,6 +1409,15 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) intel_gpu_ips_init(dev_priv); i915_audio_component_init(dev_priv); + + /* + * Some ports require correctly set-up hpd registers for detection to + * work properly (leading to ghost connected connector status), e.g. VGA + * on gm45. Hence we can only set up the initial fbdev config after hpd + * irqs are fully enabled. We do it last so that the async config + * cannot run before the connectors are registered. + */ + intel_fbdev_initial_config_async(dev); } /** -- cgit v1.2.3 From 43cee314345ac9e34e744f8c335150a17ff9a6fb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Jun 2016 09:16:54 +0100 Subject: drm/i915/fbdev: Limit the global async-domain synchronization During cleanup we have to synchronise with the async task we are using to initialise and register our fbdev. Currently, we are using a full synchronisation on the global domain, but we can restrict this to just synchronising up to our task if we remember our cookie. Whilst there, streamline the function parameters. v2: async_synchronize_cookie() takes an exclusive upper bound, to synchronize with our task we have to pass in the next cookie. v3: Drop premature disregarding of the active cookie (we need to wait until the task is complete before continuing in the teardown). v4: Refactor waiting on async to incorporate a comment explaining why we need the +1. Signed-off-by: Chris Wilson Cc: Lukas Wunner Cc: Daniel Vetter Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466497015-8509-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_fbdev.c | 39 +++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9257f08aa677..06fa25db3d32 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -159,6 +159,7 @@ struct intel_framebuffer { struct intel_fbdev { struct drm_fb_helper helper; struct intel_framebuffer *fb; + async_cookie_t cookie; int preferred_bpp; }; diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 4babefc51eb2..45a03d87a659 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -538,8 +538,7 @@ static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { .fb_probe = intelfb_create, }; -static void intel_fbdev_destroy(struct drm_device *dev, - struct intel_fbdev *ifbdev) +static void intel_fbdev_destroy(struct intel_fbdev *ifbdev) { /* We rely on the object-free to release the VMA pinning for * the info->screen_base mmaping. Leaking the VMA is simpler than @@ -552,12 +551,14 @@ static void intel_fbdev_destroy(struct drm_device *dev, drm_fb_helper_fini(&ifbdev->helper); if (ifbdev->fb) { - mutex_lock(&dev->struct_mutex); + mutex_lock(&ifbdev->helper.dev->struct_mutex); intel_unpin_fb_obj(&ifbdev->fb->base, BIT(DRM_ROTATE_0)); - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&ifbdev->helper.dev->struct_mutex); drm_framebuffer_remove(&ifbdev->fb->base); } + + kfree(ifbdev); } /* @@ -732,32 +733,44 @@ int intel_fbdev_init(struct drm_device *dev) static void intel_fbdev_initial_config(void *data, async_cookie_t cookie) { - struct drm_i915_private *dev_priv = data; - struct intel_fbdev *ifbdev = dev_priv->fbdev; + struct intel_fbdev *ifbdev = data; /* Due to peculiar init order wrt to hpd handling this is separate. */ if (drm_fb_helper_initial_config(&ifbdev->helper, ifbdev->preferred_bpp)) - intel_fbdev_fini(dev_priv->dev); + intel_fbdev_fini(ifbdev->helper.dev); } void intel_fbdev_initial_config_async(struct drm_device *dev) { - async_schedule(intel_fbdev_initial_config, to_i915(dev)); + struct intel_fbdev *ifbdev = to_i915(dev)->fbdev; + + ifbdev->cookie = async_schedule(intel_fbdev_initial_config, ifbdev); +} + +static void intel_fbdev_sync(struct intel_fbdev *ifbdev) +{ + if (!ifbdev->cookie) + return; + + /* Only serialises with all preceding async calls, hence +1 */ + async_synchronize_cookie(ifbdev->cookie + 1); + ifbdev->cookie = 0; } void intel_fbdev_fini(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (!dev_priv->fbdev) + struct intel_fbdev *ifbdev = dev_priv->fbdev; + + if (!ifbdev) return; flush_work(&dev_priv->fbdev_suspend_work); - if (!current_is_async()) - async_synchronize_full(); - intel_fbdev_destroy(dev, dev_priv->fbdev); - kfree(dev_priv->fbdev); + intel_fbdev_sync(ifbdev); + + intel_fbdev_destroy(ifbdev); dev_priv->fbdev = NULL; } -- cgit v1.2.3 From e77018f7618960f7ec0e73e63868514ff16f8ddc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Jun 2016 09:16:55 +0100 Subject: drm/i915/fbdev: Flush mode configuration before lastclose MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During lastclose, we call intel_fbdev_restore_mode() to switch back to the fbcon configuration on return to VT. However, if we have not yet finished the asynchronous fbdev initialisation, the current mode will be invalid and trigger WARNs upon application. Serialise with the outstanding initialisation if the first application exits quickly. Note that to hit this in practice requires using an unregistered async_domain as otherwise modprobe will force a full synchronisation prior to init() completing. v2: Reuse comment explaining the +1 by refactoring the wait on fbdev sync in the previous patch. Reported-by: Gustav Fägerlind Reported-by: "Li, Weinan Z" Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93580 Signed-off-by: Chris Wilson Cc: Daniel Vetter Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466497015-8509-3-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_fbdev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 45a03d87a659..16d73eaa46fb 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -840,6 +840,8 @@ void intel_fbdev_restore_mode(struct drm_device *dev) if (!ifbdev) return; + intel_fbdev_sync(ifbdev); + fb_helper = &ifbdev->helper; ret = drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper); -- cgit v1.2.3 From 0b63bb1412bf9b2d72d60e38d07bd9dfe657a382 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Mon, 20 Jun 2016 15:18:07 +0100 Subject: drm/i915/guc: index host arrays by i915 engine ID, not guc_id The ONLY places that guc_id (aka hw_id) should be used are those where the value or address is determined by and shared with the GuC firmware; specifically, when filling in the GuC-context-descriptor or the GuC addon data, or putting an entry in the GuC's work queue. It need not (and therefore should not) be used to index GuC statistics or similar host-managed tracking data. In particular, i915_guc_submit() produces (and debugfs decodes) GuC submission statistics which should be indexed by driver-engine-id rather then guc-engine-id. Signed-off-by: Dave Gordon Reviewed-by: Chris Wilson Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1466432287-5799-1-git-send-email-david.s.gordon@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 10 +++++----- drivers/gpu/drm/i915/i915_guc_submission.c | 2 +- drivers/gpu/drm/i915/intel_guc.h | 7 ++++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5b7526697838..7d63af03debc 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2544,9 +2544,9 @@ static void i915_guc_client_info(struct seq_file *m, for_each_engine(engine, dev_priv) { seq_printf(m, "\tSubmissions: %llu %s\n", - client->submissions[engine->guc_id], + client->submissions[engine->id], engine->name); - tot += client->submissions[engine->guc_id]; + tot += client->submissions[engine->id]; } seq_printf(m, "\tTotal: %llu\n", tot); } @@ -2587,9 +2587,9 @@ static int i915_guc_info(struct seq_file *m, void *data) seq_printf(m, "\nGuC submissions:\n"); for_each_engine(engine, dev_priv) { seq_printf(m, "\t%-24s: %10llu, last seqno 0x%08x\n", - engine->name, guc.submissions[engine->guc_id], - guc.last_seqno[engine->guc_id]); - total += guc.submissions[engine->guc_id]; + engine->name, guc.submissions[engine->id], + guc.last_seqno[engine->id]); + total += guc.submissions[engine->id]; } seq_printf(m, "\t%s: %llu\n", "Total", total); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 22a55ac4e51c..01c7cdf26fc1 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -582,7 +582,7 @@ static int guc_ring_doorbell(struct i915_guc_client *gc) */ int i915_guc_submit(struct drm_i915_gem_request *rq) { - unsigned int engine_id = rq->engine->guc_id; + unsigned int engine_id = rq->engine->id; struct intel_guc *guc = &rq->i915->guc; struct i915_guc_client *client = guc->execbuf_client; int b_ret; diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 4df80cc9a291..3e3e743740c0 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -26,6 +26,7 @@ #include "intel_guc_fwif.h" #include "i915_guc_reg.h" +#include "intel_ringbuffer.h" struct drm_i915_gem_request; @@ -86,7 +87,7 @@ struct i915_guc_client { int retcode; /* Per-engine counts of GuC submissions */ - uint64_t submissions[GUC_MAX_ENGINES_NUM]; + uint64_t submissions[I915_NUM_ENGINES]; }; enum intel_guc_fw_status { @@ -143,8 +144,8 @@ struct intel_guc { uint32_t action_fail; /* Total number of failures */ int32_t action_err; /* Last error code */ - uint64_t submissions[GUC_MAX_ENGINES_NUM]; - uint32_t last_seqno[GUC_MAX_ENGINES_NUM]; + uint64_t submissions[I915_NUM_ENGINES]; + uint32_t last_seqno[I915_NUM_ENGINES]; }; /* intel_guc_loader.c */ -- cgit v1.2.3 From 2b83c4c49abc908ce2863df71067079a6ad8dd86 Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Mon, 20 Jun 2016 11:58:27 +0200 Subject: drm/i915: Set softmin frequency on idle->busy transition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the GPU load is low enough, it's possible that we'll be stuck at idle frequency rather than transition into softmin frequency requested by userspace. v2: Use intel_set_rps, drop vlv_set_idle v3: Back to vlv_set_idle, clamp to valid range v4: Place intel_set_rps at the end References: https://bugs.freedesktop.org/show_bug.cgi?id=89728 Cc: Chris Wilson Cc: Imre Deak Cc: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Michał Winiarski Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1466416707-12075-1-git-send-email-michal.winiarski@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 658a75659657..c94521cc476c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4844,6 +4844,12 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) gen6_rps_reset_ei(dev_priv); I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); + + /* Ensure we start at the user's desired frequency */ + intel_set_rps(dev_priv, + clamp(dev_priv->rps.cur_freq, + dev_priv->rps.min_freq_softlimit, + dev_priv->rps.max_freq_softlimit)); } mutex_unlock(&dev_priv->rps.hw_lock); } -- cgit v1.2.3 From 77ca04ccf0c9dc00104da8336024a6593b6305a6 Mon Sep 17 00:00:00 2001 From: Zhi Wang Date: Mon, 20 Jun 2016 08:17:02 -0400 Subject: drm/i915: Set the access right of kernel param "i915.enable_gvt" to read-only. The access right of kernel param "i915.enable_gvt" should be read-only as it only applies during module load (and is not *runtime* writable). Cc: Chris Wilson Signed-off-by: Zhi Wang Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1466425022-3709-1-git-send-email-zhi.a.wang@intel.com --- drivers/gpu/drm/i915/i915_params.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 7effe68d552c..8b13bfa47fba 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -224,6 +224,6 @@ module_param_named(enable_dpcd_backlight, i915.enable_dpcd_backlight, bool, 0600 MODULE_PARM_DESC(enable_dpcd_backlight, "Enable support for DPCD backlight control (default:false)"); -module_param_named(enable_gvt, i915.enable_gvt, bool, 0600); +module_param_named(enable_gvt, i915.enable_gvt, bool, 0400); MODULE_PARM_DESC(enable_gvt, "Enable support for Intel GVT-g graphics virtualization host support(default:false)"); -- cgit v1.2.3 From 7822492fd21a44eeb3568082b0ab915df7388061 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Jun 2016 12:04:21 +0100 Subject: drm/i915/gvt: Mark i915.enable_gvt as false if loading fails If we update the value of i915.enable_gvt should we fail to load GVT, userspace can easily detect when it fails to load as requested. Testcase: igt/gvt_basic Signed-off-by: Chris Wilson Cc: Zhi Wang Reviewed-by: Zhi Wang Link: http://patchwork.freedesktop.org/patch/msgid/1466507234-23242-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_gvt.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_gvt.c b/drivers/gpu/drm/i915/intel_gvt.c index 9fa458ce40a6..434f4d5c553d 100644 --- a/drivers/gpu/drm/i915/intel_gvt.c +++ b/drivers/gpu/drm/i915/intel_gvt.c @@ -63,7 +63,7 @@ int intel_gvt_init(struct drm_i915_private *dev_priv) if (!is_supported_device(dev_priv)) { DRM_DEBUG_DRIVER("Unsupported device. GVT-g is disabled\n"); - return 0; + goto bail; } /* @@ -72,16 +72,20 @@ int intel_gvt_init(struct drm_i915_private *dev_priv) ret = intel_gvt_init_host(); if (ret) { DRM_DEBUG_DRIVER("Not in host or MPT modules not found\n"); - return 0; + goto bail; } ret = intel_gvt_init_device(dev_priv); if (ret) { DRM_DEBUG_DRIVER("Fail to init GVT device\n"); - return 0; + goto bail; } return 0; + +bail: + i915.enable_gvt = 0; + return 0; } /** -- cgit v1.2.3 From 26875fe50285eef06239ba7dd31da7950fea0d21 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 20 Jun 2016 15:57:36 +0200 Subject: drm/i915: Use connector->name in drrs debugfs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes relying on intel_encoder->type, which may be set to unknown. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466431059-8919-2-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_debugfs.c | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 7d63af03debc..c42281bca143 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3374,31 +3374,16 @@ static int i915_ddb_info(struct seq_file *m, void *unused) static void drrs_status_per_crtc(struct seq_file *m, struct drm_device *dev, struct intel_crtc *intel_crtc) { - struct intel_encoder *intel_encoder; struct drm_i915_private *dev_priv = dev->dev_private; struct i915_drrs *drrs = &dev_priv->drrs; int vrefresh = 0; + struct drm_connector *connector; - for_each_encoder_on_crtc(dev, &intel_crtc->base, intel_encoder) { - /* Encoder connected on this CRTC */ - switch (intel_encoder->type) { - case INTEL_OUTPUT_EDP: - seq_puts(m, "eDP:\n"); - break; - case INTEL_OUTPUT_DSI: - seq_puts(m, "DSI:\n"); - break; - case INTEL_OUTPUT_HDMI: - seq_puts(m, "HDMI:\n"); - break; - case INTEL_OUTPUT_DISPLAYPORT: - seq_puts(m, "DP:\n"); - break; - default: - seq_printf(m, "Other encoder (id=%d).\n", - intel_encoder->type); - return; - } + drm_for_each_connector(connector, dev) { + if (connector->state->crtc != &intel_crtc->base) + continue; + + seq_printf(m, "%s:\n", connector->name); } if (dev_priv->vbt.drrs_type == STATIC_DRRS_SUPPORT) @@ -3461,18 +3446,16 @@ static int i915_drrs_status(struct seq_file *m, void *unused) struct intel_crtc *intel_crtc; int active_crtc_cnt = 0; + drm_modeset_lock_all(dev); for_each_intel_crtc(dev, intel_crtc) { - drm_modeset_lock(&intel_crtc->base.mutex, NULL); - if (intel_crtc->base.state->active) { active_crtc_cnt++; seq_printf(m, "\nCRTC %d: ", active_crtc_cnt); drrs_status_per_crtc(m, dev, intel_crtc); } - - drm_modeset_unlock(&intel_crtc->base.mutex); } + drm_modeset_unlock_all(dev); if (!active_crtc_cnt) seq_puts(m, "No active crtc found\n"); -- cgit v1.2.3 From b6dabe3bbd1418a6ed71adf7bb9a940e57ccfdd8 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 20 Jun 2016 15:57:37 +0200 Subject: drm/i915: Use connector_type instead of intel_encoder->type for DP. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466431059-8919-3-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_debugfs.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c42281bca143..179bb8bba80d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2950,7 +2950,7 @@ static void intel_dp_info(struct seq_file *m, seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]); seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio)); - if (intel_encoder->type == INTEL_OUTPUT_EDP) + if (intel_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) intel_panel_info(m, &intel_connector->panel); } @@ -3473,17 +3473,23 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - struct drm_encoder *encoder; struct intel_encoder *intel_encoder; struct intel_digital_port *intel_dig_port; + struct drm_connector *connector; + drm_modeset_lock_all(dev); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - intel_encoder = to_intel_encoder(encoder); - if (intel_encoder->type != INTEL_OUTPUT_DISPLAYPORT) + drm_for_each_connector(connector, dev) { + if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) continue; - intel_dig_port = enc_to_dig_port(encoder); + + intel_encoder = intel_attached_encoder(connector); + if (!intel_encoder || intel_encoder->type == INTEL_OUTPUT_DP_MST) + continue; + + intel_dig_port = enc_to_dig_port(&intel_encoder->base); if (!intel_dig_port->dp.can_mst) continue; + seq_printf(m, "MST Source Port %c\n", port_name(intel_dig_port->port)); drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr); -- cgit v1.2.3 From 26c17cf65cd69733fde1487797d081fb54b08e05 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 20 Jun 2016 15:57:38 +0200 Subject: drm/i915: Use atomic state and connector_type in i915_sink_src MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DPMS is unreliable, use crtc->state. Signed-off-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466431059-8919-4-git-send-email-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/i915/i915_debugfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 179bb8bba80d..8fde9594cad8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2701,7 +2701,6 @@ static int i915_sink_crc(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct intel_encoder *encoder; struct intel_connector *connector; struct intel_dp *intel_dp = NULL; int ret; @@ -2709,18 +2708,19 @@ static int i915_sink_crc(struct seq_file *m, void *data) drm_modeset_lock_all(dev); for_each_intel_connector(dev, connector) { + struct drm_crtc *crtc; - if (connector->base.dpms != DRM_MODE_DPMS_ON) + if (!connector->base.state->best_encoder) continue; - if (!connector->base.encoder) + crtc = connector->base.state->crtc; + if (!crtc->state->active) continue; - encoder = to_intel_encoder(connector->base.encoder); - if (encoder->type != INTEL_OUTPUT_EDP) + if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP) continue; - intel_dp = enc_to_intel_dp(&encoder->base); + intel_dp = enc_to_intel_dp(connector->base.state->best_encoder); ret = intel_dp_sink_crc(intel_dp, crc); if (ret) -- cgit v1.2.3 From ee648a74db486360ad34d13b740f5237f191320f Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 21 Jun 2016 12:00:38 +0200 Subject: drm/i915: Use connector_type for printing in intel_connector_info, v2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of looking at encoder->type, which may be set to UNKNOWN, use connector->connector_type. Info cannot be printed for MST connectors which may have a NULL encoder, return early in that case. Changes since v1: - Whitelist encoder types for HDMI and LVDS. - Fix oops on MST. - Do not list encoder types for eDP/DP, they're always valid. Signed-off-by: Maarten Lankhorst Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/7cf34026-392d-01ec-e79b-e91919d1d783@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 8fde9594cad8..9989b6a26b17 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2989,14 +2989,26 @@ static void intel_connector_info(struct seq_file *m, seq_printf(m, "\tCEA rev: %d\n", connector->display_info.cea_rev); } - if (intel_encoder) { - if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT || - intel_encoder->type == INTEL_OUTPUT_EDP) - intel_dp_info(m, intel_connector); - else if (intel_encoder->type == INTEL_OUTPUT_HDMI) - intel_hdmi_info(m, intel_connector); - else if (intel_encoder->type == INTEL_OUTPUT_LVDS) + + if (!intel_encoder || intel_encoder->type == INTEL_OUTPUT_DP_MST) + return; + + switch (connector->connector_type) { + case DRM_MODE_CONNECTOR_DisplayPort: + case DRM_MODE_CONNECTOR_eDP: + intel_dp_info(m, intel_connector); + break; + case DRM_MODE_CONNECTOR_LVDS: + if (intel_encoder->type == INTEL_OUTPUT_LVDS) intel_lvds_info(m, intel_connector); + break; + case DRM_MODE_CONNECTOR_HDMIA: + if (intel_encoder->type == INTEL_OUTPUT_HDMI || + intel_encoder->type == INTEL_OUTPUT_UNKNOWN) + intel_hdmi_info(m, intel_connector); + break; + default: + break; } seq_printf(m, "\tmodes:\n"); -- cgit v1.2.3 From 612515121b3e64f3bb060076d1799f1ce943630f Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 21 Jun 2016 15:07:14 +0100 Subject: drm/i915/guc: Remove one unnecessary variable No need for local struct drm_device * since dev_priv is the correct thing to pass in to NEEDS_WaRsDisableCoarsePowerGating anyway. Changed the macro definition for the latter to reflect that as well. v2: Alignment bikeshed. Signed-off-by: Tvrtko Ursulin Cc: Dave Gordon Reviewed-by: Chris Wilson Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466518034-24838-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 7 ++++--- drivers/gpu/drm/i915/i915_guc_submission.c | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9e09d91d4c7a..b6c8ce484011 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2789,9 +2789,10 @@ struct drm_i915_cmd_table { #define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev)) /* WaRsDisableCoarsePowerGating:skl,bxt */ -#define NEEDS_WaRsDisableCoarsePowerGating(dev) (IS_BXT_REVID(dev, 0, BXT_REVID_A1) || \ - IS_SKL_GT3(dev) || \ - IS_SKL_GT4(dev)) +#define NEEDS_WaRsDisableCoarsePowerGating(dev_priv) \ + (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1) || \ + IS_SKL_GT3(dev_priv) || \ + IS_SKL_GT4(dev_priv)) /* * dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 01c7cdf26fc1..355b6475e74c 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -153,12 +153,11 @@ static int host2guc_sample_forcewake(struct intel_guc *guc, struct i915_guc_client *client) { struct drm_i915_private *dev_priv = guc_to_i915(guc); - struct drm_device *dev = dev_priv->dev; u32 data[2]; data[0] = HOST2GUC_ACTION_SAMPLE_FORCEWAKE; /* WaRsDisableCoarsePowerGating:skl,bxt */ - if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev)) + if (!intel_enable_rc6() || NEEDS_WaRsDisableCoarsePowerGating(dev_priv)) data[1] = 0; else /* bit 0 and 1 are for Render and Media domain separately */ -- cgit v1.2.3 From 97a824e1565e55c5be69f4ab36eb3297aa714091 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Jun 2016 11:51:47 +0300 Subject: drm/i915/ibx, cpt: Don't attempt to register eDP if LVDS was detected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Atm on IBX/CPT we attempt to detect if eDP is present even if LVDS was already detected and an encoder for it was registered. This involves trying to read out the eDP DPCD, which in turn needs the same power sequencer that LVDS uses. Poking at the VDD line at an unexpected time may or may not interfere with the LVDS panel, but it's probably safer to prevent this. Registering both an LVDS and an eDP connector would also present a similar problem accessing the shared PPS at any point later in an unexpected way. We also need this to be able fix PPS initialization before its first use in the next patch. For that we want to be sure that PPS is not in use by LVDS. v2: - Split out the PPS init fix to a separate patch. (Chris) - Add comment about eDP init depending on LVDS init. (Chris) - Make the use of the intel_encoder ptr less error prone. v3: - Use IBX/CPT reference instead of the incorrect ILK, add a WARN about this. (Ville) v4: - Use a helper to get the lvds encoder instead of opencoding the same. (Ville) CC: Ville Syrjälä CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson (v2) Reviewed-by: Ville Syrjälä (v3) Link: http://patchwork.freedesktop.org/patch/msgid/1466499109-20240-2-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_display.c | 5 +++++ drivers/gpu/drm/i915/intel_dp.c | 13 +++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_lvds.c | 22 ++++++++++++---------- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8c6f4e2a2cb8..b6bb43875a03 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14708,6 +14708,11 @@ static void intel_setup_outputs(struct drm_device *dev) struct intel_encoder *encoder; bool dpd_is_edp = false; + /* + * intel_edp_init_connector() depends on this completing first, to + * prevent the registeration of both eDP and LVDS and the incorrect + * sharing of the PPS. + */ intel_lvds_init(dev); if (intel_crt_present(dev)) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3cdea4d7a917..9493c8f76538 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5313,6 +5313,19 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, if (!is_edp(intel_dp)) return true; + /* + * On IBX/CPT we may get here with LVDS already registered. Since the + * driver uses the only internal power sequencer available for both + * eDP and LVDS bail out early in this case to prevent interfering + * with an already powered-on LVDS power sequencer. + */ + if (intel_get_lvds_encoder(dev)) { + WARN_ON(!(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))); + DRM_INFO("LVDS was detected, not registering eDP\n"); + + return false; + } + pps_lock(intel_dp); intel_edp_panel_vdd_sanitize(intel_dp); pps_unlock(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 06fa25db3d32..21ba3df05241 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1460,6 +1460,7 @@ void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable); /* intel_lvds.c */ void intel_lvds_init(struct drm_device *dev); +struct intel_encoder *intel_get_lvds_encoder(struct drm_device *dev); bool intel_is_dual_link_lvds(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e06b9036bebc..72096fd28023 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -809,20 +809,22 @@ static const struct dmi_system_id intel_dual_link_lvds[] = { { } /* terminating entry */ }; -bool intel_is_dual_link_lvds(struct drm_device *dev) +struct intel_encoder *intel_get_lvds_encoder(struct drm_device *dev) { - struct intel_encoder *encoder; - struct intel_lvds_encoder *lvds_encoder; + struct intel_encoder *intel_encoder; - for_each_intel_encoder(dev, encoder) { - if (encoder->type == INTEL_OUTPUT_LVDS) { - lvds_encoder = to_lvds_encoder(&encoder->base); + for_each_intel_encoder(dev, intel_encoder) + if (intel_encoder->type == INTEL_OUTPUT_LVDS) + return intel_encoder; - return lvds_encoder->is_dual_link; - } - } + return NULL; +} - return false; +bool intel_is_dual_link_lvds(struct drm_device *dev) +{ + struct intel_encoder *encoder = intel_get_lvds_encoder(dev); + + return encoder && to_lvds_encoder(&encoder->base)->is_dual_link; } static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) -- cgit v1.2.3 From 0080b5da392243af673e752b5681e6388ede7da0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Jun 2016 11:51:48 +0300 Subject: drm/i915: Initialize the PPS HW before its first use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The initial DPCD read for eDP detection involves using the PPS, but so far we only initialized the PPS registers after the DPCD read. The reason this was done so far is to preserve a possible LVDS PPS HW setup if LVDS is detected but eDP is not. This is not an issue any more after the previous patch, so we can move the init earlier now. This was caught by CI with the PPS sanity checks in place and the initial eDP DPCD readout waiting for the panel power cycle timeout without the PPS registers being initialized. CC: Ville Syrjälä CC: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1466499109-20240-3-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9493c8f76538..55b31934e966 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5328,6 +5328,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, pps_lock(intel_dp); intel_edp_panel_vdd_sanitize(intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); pps_unlock(intel_dp); /* Cache DPCD and EDID for edp. */ @@ -5344,11 +5345,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, return false; } - /* We now know it's not a ghost, init power sequence regs. */ - pps_lock(intel_dp); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); - pps_unlock(intel_dp); - mutex_lock(&dev->mode_config.mutex); edid = drm_get_edid(connector, &intel_dp->aux.ddc); if (edid) { -- cgit v1.2.3 From b4d06ede4e301c4d11bbf8fd58ebe2aad2618769 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 21 Jun 2016 11:51:49 +0300 Subject: drm/i915: Group all the PPS init steps to one place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the early PPS initialization calls next to the rest of PPS initialization steps. This allows us to forgo a duplicated call to intel_dp_init_panel_power_sequencer_registers() on VLV/CHV. This will swap the order of DP AUX registration wrt. PPS initialization. There is an existing race here in case of a user space access via the DPAUX device node after DP AUX registration and before calling intel_dp_init_panel_power_sequencer_registers(), but this change won't make this worse. The fix for this is to separate DP AUX initialization and registration, that's a separate work already underway. The order of MST wrt. PPS init as well as the order of intel_dp_init_panel_power_sequencer_registers() wrt. intel_edp_panel_vdd_sanitize() also swap, which is ok, there are no dependencies between these steps. Suggested by Ville. CC: Ville Syrjälä Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1466499109-20240-4-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 46 +++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 55b31934e966..b160c45864a8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5327,8 +5327,18 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } pps_lock(intel_dp); + + intel_dp_init_panel_power_timestamps(intel_dp); + + if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { + vlv_initial_power_sequencer_setup(intel_dp); + } else { + intel_dp_init_panel_power_sequencer(dev, intel_dp); + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + } + intel_edp_panel_vdd_sanitize(intel_dp); - intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + pps_unlock(intel_dp); /* Cache DPCD and EDID for edp. */ @@ -5342,7 +5352,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } else { /* if this fails, presume the device is a ghost */ DRM_INFO("failed to retrieve link info, disabling eDP\n"); - return false; + goto out_vdd_off; } mutex_lock(&dev->mode_config.mutex); @@ -5412,6 +5422,18 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, intel_panel_setup_backlight(connector, pipe); return true; + +out_vdd_off: + cancel_delayed_work_sync(&intel_dp->panel_vdd_work); + /* + * vdd might still be enabled do to the delayed vdd off. + * Make sure vdd is actually turned off here. + */ + pps_lock(intel_dp); + edp_panel_vdd_off_sync(intel_dp); + pps_unlock(intel_dp); + + return false; } bool @@ -5518,16 +5540,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, BUG(); } - if (is_edp(intel_dp)) { - pps_lock(intel_dp); - intel_dp_init_panel_power_timestamps(intel_dp); - if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) - vlv_initial_power_sequencer_setup(intel_dp); - else - intel_dp_init_panel_power_sequencer(dev, intel_dp); - pps_unlock(intel_dp); - } - ret = intel_dp_aux_init(intel_dp, intel_connector); if (ret) goto fail; @@ -5560,16 +5572,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, return true; fail: - if (is_edp(intel_dp)) { - cancel_delayed_work_sync(&intel_dp->panel_vdd_work); - /* - * vdd might still be enabled do to the delayed vdd off. - * Make sure vdd is actually turned off here. - */ - pps_lock(intel_dp); - edp_panel_vdd_off_sync(intel_dp); - pps_unlock(intel_dp); - } drm_connector_unregister(connector); drm_connector_cleanup(connector); -- cgit v1.2.3 From 78597996370cbe00b739295c7241a1c6a08b4c44 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 16 Jun 2016 16:37:20 +0300 Subject: drm/i915/bxt: Fix PPS lost state after suspend breaking eDP link training MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PPS registers are backed by power well #0 and as such may be reset after system or runtime suspend (both implying a possible DC9 transition). Fix this by reusing the VLV/CHV PPS pipe-reassignment logic. The difference on BXT is that the PPS instances are not pipe but port (or more accurately pin) specific, so we only need to care about the lost HW state. As opposed to VLV/CHV the SW state is fixed and initialized during connector init. This also paves the way towards using the actual port->PPS instance mapping based on VBT. This fixes eDP link training errors on BXT after suspend, where we started the link training too early due to an incorrect T3 (panel power on) register value. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96436 Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1466084243-5388-2-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 71 +++++++++++++++++++++++---------- drivers/gpu/drm/i915/intel_drv.h | 7 +++- drivers/gpu/drm/i915/intel_runtime_pm.c | 3 +- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b160c45864a8..d8cc4f373d00 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -426,6 +426,37 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) return intel_dp->pps_pipe; } +static int +bxt_power_sequencer_idx(struct intel_dp *intel_dp) +{ + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + lockdep_assert_held(&dev_priv->pps_mutex); + + /* We should never land here with regular DP ports */ + WARN_ON(!is_edp(intel_dp)); + + /* + * TODO: BXT has 2 PPS instances. The correct port->PPS instance + * mapping needs to be retrieved from VBT, for now just hard-code to + * use instance #0 always. + */ + if (!intel_dp->pps_reset) + return 0; + + intel_dp->pps_reset = false; + + /* + * Only the HW needs to be reprogrammed, the SW state is fixed and + * has been setup during connector init. + */ + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); + + return 0; +} + typedef bool (*vlv_pipe_check)(struct drm_i915_private *dev_priv, enum pipe pipe); @@ -507,12 +538,13 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) intel_dp_init_panel_power_sequencer_registers(dev, intel_dp); } -void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv) +void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; struct intel_encoder *encoder; - if (WARN_ON(!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev))) + if (WARN_ON(!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) && + !IS_BROXTON(dev))) return; /* @@ -532,7 +564,10 @@ void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv) continue; intel_dp = enc_to_intel_dp(&encoder->base); - intel_dp->pps_pipe = INVALID_PIPE; + if (IS_BROXTON(dev)) + intel_dp->pps_reset = true; + else + intel_dp->pps_pipe = INVALID_PIPE; } } @@ -542,7 +577,7 @@ _pp_ctrl_reg(struct intel_dp *intel_dp) struct drm_device *dev = intel_dp_to_dev(intel_dp); if (IS_BROXTON(dev)) - return BXT_PP_CONTROL(0); + return BXT_PP_CONTROL(bxt_power_sequencer_idx(intel_dp)); else if (HAS_PCH_SPLIT(dev)) return PCH_PP_CONTROL; else @@ -555,7 +590,7 @@ _pp_stat_reg(struct intel_dp *intel_dp) struct drm_device *dev = intel_dp_to_dev(intel_dp); if (IS_BROXTON(dev)) - return BXT_PP_STATUS(0); + return BXT_PP_STATUS(bxt_power_sequencer_idx(intel_dp)); else if (HAS_PCH_SPLIT(dev)) return PCH_PP_STATUS; else @@ -4719,14 +4754,11 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, return; if (IS_BROXTON(dev)) { - /* - * TODO: BXT has 2 sets of PPS registers. - * Correct Register for Broxton need to be identified - * using VBT. hardcoding for now - */ - pp_ctrl_reg = BXT_PP_CONTROL(0); - pp_on_reg = BXT_PP_ON_DELAYS(0); - pp_off_reg = BXT_PP_OFF_DELAYS(0); + int idx = bxt_power_sequencer_idx(intel_dp); + + pp_ctrl_reg = BXT_PP_CONTROL(idx); + pp_on_reg = BXT_PP_ON_DELAYS(idx); + pp_off_reg = BXT_PP_OFF_DELAYS(idx); } else if (HAS_PCH_SPLIT(dev)) { pp_ctrl_reg = PCH_PP_CONTROL; pp_on_reg = PCH_PP_ON_DELAYS; @@ -4839,14 +4871,11 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, lockdep_assert_held(&dev_priv->pps_mutex); if (IS_BROXTON(dev)) { - /* - * TODO: BXT has 2 sets of PPS registers. - * Correct Register for Broxton need to be identified - * using VBT. hardcoding for now - */ - pp_ctrl_reg = BXT_PP_CONTROL(0); - pp_on_reg = BXT_PP_ON_DELAYS(0); - pp_off_reg = BXT_PP_OFF_DELAYS(0); + int idx = bxt_power_sequencer_idx(intel_dp); + + pp_ctrl_reg = BXT_PP_CONTROL(idx); + pp_on_reg = BXT_PP_ON_DELAYS(idx); + pp_off_reg = BXT_PP_OFF_DELAYS(idx); } else if (HAS_PCH_SPLIT(dev)) { pp_on_reg = PCH_PP_ON_DELAYS; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 21ba3df05241..59e1f56a9232 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -870,6 +870,11 @@ struct intel_dp { * this port. Only relevant on VLV/CHV. */ enum pipe pps_pipe; + /* + * Set if the sequencer may be reset due to a power transition, + * requiring a reinitialization. Only relevant on BXT. + */ + bool pps_reset; struct edp_power_seq pps_delays; bool can_mst; /* this port supports mst */ @@ -1347,7 +1352,7 @@ void intel_dp_mst_resume(struct drm_device *dev); int intel_dp_max_link_rate(struct intel_dp *intel_dp); int intel_dp_rate_select(struct intel_dp *intel_dp, int rate); void intel_dp_hot_plug(struct intel_encoder *intel_encoder); -void vlv_power_sequencer_reset(struct drm_i915_private *dev_priv); +void intel_power_sequencer_reset(struct drm_i915_private *dev_priv); uint32_t intel_dp_pack_aux(const uint8_t *src, int src_bytes); void intel_plane_destroy(struct drm_plane *plane); void intel_edp_drrs_enable(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index e856d49d6dc3..22b46f5f0273 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -578,6 +578,7 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv) DRM_DEBUG_KMS("Enabling DC9\n"); + intel_power_sequencer_reset(dev_priv); gen9_set_dc_state(dev_priv, DC_STATE_EN_DC9); } @@ -1112,7 +1113,7 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv) /* make sure we're done processing display irqs */ synchronize_irq(dev_priv->dev->irq); - vlv_power_sequencer_reset(dev_priv); + intel_power_sequencer_reset(dev_priv); } static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, -- cgit v1.2.3 From 8e8232d5187831dfa81a95eb55a857b10caf549f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 16 Jun 2016 16:37:21 +0300 Subject: drm/i915: Deduplicate PPS register retrieval MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional change. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1466084243-5388-3-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 131 ++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 66 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d8cc4f373d00..b6b00cfaa04c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -571,30 +571,64 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) } } +struct pps_registers { + i915_reg_t pp_ctrl; + i915_reg_t pp_stat; + i915_reg_t pp_on; + i915_reg_t pp_off; + i915_reg_t pp_div; +}; + +static void intel_pps_get_registers(struct drm_i915_private *dev_priv, + struct intel_dp *intel_dp, + struct pps_registers *regs) +{ + memset(regs, 0, sizeof(*regs)); + + if (IS_BROXTON(dev_priv)) { + int idx = bxt_power_sequencer_idx(intel_dp); + + regs->pp_ctrl = BXT_PP_CONTROL(idx); + regs->pp_stat = BXT_PP_STATUS(idx); + regs->pp_on = BXT_PP_ON_DELAYS(idx); + regs->pp_off = BXT_PP_OFF_DELAYS(idx); + } else if (HAS_PCH_SPLIT(dev_priv)) { + regs->pp_ctrl = PCH_PP_CONTROL; + regs->pp_stat = PCH_PP_STATUS; + regs->pp_on = PCH_PP_ON_DELAYS; + regs->pp_off = PCH_PP_OFF_DELAYS; + regs->pp_div = PCH_PP_DIVISOR; + } else { + enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); + + regs->pp_ctrl = VLV_PIPE_PP_CONTROL(pipe); + regs->pp_stat = VLV_PIPE_PP_STATUS(pipe); + regs->pp_on = VLV_PIPE_PP_ON_DELAYS(pipe); + regs->pp_off = VLV_PIPE_PP_OFF_DELAYS(pipe); + regs->pp_div = VLV_PIPE_PP_DIVISOR(pipe); + } +} + static i915_reg_t _pp_ctrl_reg(struct intel_dp *intel_dp) { - struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct pps_registers regs; - if (IS_BROXTON(dev)) - return BXT_PP_CONTROL(bxt_power_sequencer_idx(intel_dp)); - else if (HAS_PCH_SPLIT(dev)) - return PCH_PP_CONTROL; - else - return VLV_PIPE_PP_CONTROL(vlv_power_sequencer_pipe(intel_dp)); + intel_pps_get_registers(to_i915(intel_dp_to_dev(intel_dp)), intel_dp, + ®s); + + return regs.pp_ctrl; } static i915_reg_t _pp_stat_reg(struct intel_dp *intel_dp) { - struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct pps_registers regs; - if (IS_BROXTON(dev)) - return BXT_PP_STATUS(bxt_power_sequencer_idx(intel_dp)); - else if (HAS_PCH_SPLIT(dev)) - return PCH_PP_STATUS; - else - return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp)); + intel_pps_get_registers(to_i915(intel_dp_to_dev(intel_dp)), intel_dp, + ®s); + + return regs.pp_stat; } /* Reboot notifier handler to shutdown panel power to guarantee T12 timing @@ -4745,7 +4779,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, struct edp_power_seq cur, vbt, spec, *final = &intel_dp->pps_delays; u32 pp_on, pp_off, pp_div = 0, pp_ctl = 0; - i915_reg_t pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg; + struct pps_registers regs; lockdep_assert_held(&dev_priv->pps_mutex); @@ -4753,35 +4787,17 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, if (final->t11_t12 != 0) return; - if (IS_BROXTON(dev)) { - int idx = bxt_power_sequencer_idx(intel_dp); - - pp_ctrl_reg = BXT_PP_CONTROL(idx); - pp_on_reg = BXT_PP_ON_DELAYS(idx); - pp_off_reg = BXT_PP_OFF_DELAYS(idx); - } else if (HAS_PCH_SPLIT(dev)) { - pp_ctrl_reg = PCH_PP_CONTROL; - pp_on_reg = PCH_PP_ON_DELAYS; - pp_off_reg = PCH_PP_OFF_DELAYS; - pp_div_reg = PCH_PP_DIVISOR; - } else { - enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); - - pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe); - pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe); - pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe); - pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe); - } + intel_pps_get_registers(dev_priv, intel_dp, ®s); /* Workaround: Need to write PP_CONTROL with the unlock key as * the very first thing. */ pp_ctl = ironlake_get_pp_control(intel_dp); - pp_on = I915_READ(pp_on_reg); - pp_off = I915_READ(pp_off_reg); + pp_on = I915_READ(regs.pp_on); + pp_off = I915_READ(regs.pp_off); if (!IS_BROXTON(dev)) { - I915_WRITE(pp_ctrl_reg, pp_ctl); - pp_div = I915_READ(pp_div_reg); + I915_WRITE(regs.pp_ctrl, pp_ctl); + pp_div = I915_READ(regs.pp_div); } /* Pull timing values out of registers */ @@ -4864,30 +4880,13 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, struct drm_i915_private *dev_priv = dev->dev_private; u32 pp_on, pp_off, pp_div, port_sel = 0; int div = dev_priv->rawclk_freq / 1000; - i915_reg_t pp_on_reg, pp_off_reg, pp_div_reg, pp_ctrl_reg; + struct pps_registers regs; enum port port = dp_to_dig_port(intel_dp)->port; const struct edp_power_seq *seq = &intel_dp->pps_delays; lockdep_assert_held(&dev_priv->pps_mutex); - if (IS_BROXTON(dev)) { - int idx = bxt_power_sequencer_idx(intel_dp); - - pp_ctrl_reg = BXT_PP_CONTROL(idx); - pp_on_reg = BXT_PP_ON_DELAYS(idx); - pp_off_reg = BXT_PP_OFF_DELAYS(idx); - - } else if (HAS_PCH_SPLIT(dev)) { - pp_on_reg = PCH_PP_ON_DELAYS; - pp_off_reg = PCH_PP_OFF_DELAYS; - pp_div_reg = PCH_PP_DIVISOR; - } else { - enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); - - pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe); - pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe); - pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe); - } + intel_pps_get_registers(dev_priv, intel_dp, ®s); /* * And finally store the new values in the power sequencer. The @@ -4904,7 +4903,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, /* Compute the divisor for the pp clock, simply match the Bspec * formula. */ if (IS_BROXTON(dev)) { - pp_div = I915_READ(pp_ctrl_reg); + pp_div = I915_READ(regs.pp_ctrl); pp_div &= ~BXT_POWER_CYCLE_DELAY_MASK; pp_div |= (DIV_ROUND_UP((seq->t11_t12 + 1), 1000) << BXT_POWER_CYCLE_DELAY_SHIFT); @@ -4927,19 +4926,19 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, pp_on |= port_sel; - I915_WRITE(pp_on_reg, pp_on); - I915_WRITE(pp_off_reg, pp_off); + I915_WRITE(regs.pp_on, pp_on); + I915_WRITE(regs.pp_off, pp_off); if (IS_BROXTON(dev)) - I915_WRITE(pp_ctrl_reg, pp_div); + I915_WRITE(regs.pp_ctrl, pp_div); else - I915_WRITE(pp_div_reg, pp_div); + I915_WRITE(regs.pp_div, pp_div); DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n", - I915_READ(pp_on_reg), - I915_READ(pp_off_reg), + I915_READ(regs.pp_on), + I915_READ(regs.pp_off), IS_BROXTON(dev) ? - (I915_READ(pp_ctrl_reg) & BXT_POWER_CYCLE_DELAY_MASK) : - I915_READ(pp_div_reg)); + (I915_READ(regs.pp_ctrl) & BXT_POWER_CYCLE_DELAY_MASK) : + I915_READ(regs.pp_div)); } /** -- cgit v1.2.3 From 546486184c46070d83e08cc69e039e82021c6fc6 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 16 Jun 2016 16:37:22 +0300 Subject: drm/i915: Factor out helper to read out PPS HW state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be needed by the next patch too so factor it out. No functional change. Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1466084243-5388-4-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 56 +++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index b6b00cfaa04c..6992915f8642 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4772,21 +4772,12 @@ static void intel_dp_init_panel_power_timestamps(struct intel_dp *intel_dp) } static void -intel_dp_init_panel_power_sequencer(struct drm_device *dev, - struct intel_dp *intel_dp) +intel_pps_readout_hw_state(struct drm_i915_private *dev_priv, + struct intel_dp *intel_dp, struct edp_power_seq *seq) { - struct drm_i915_private *dev_priv = dev->dev_private; - struct edp_power_seq cur, vbt, spec, - *final = &intel_dp->pps_delays; u32 pp_on, pp_off, pp_div = 0, pp_ctl = 0; struct pps_registers regs; - lockdep_assert_held(&dev_priv->pps_mutex); - - /* already initialized? */ - if (final->t11_t12 != 0) - return; - intel_pps_get_registers(dev_priv, intel_dp, ®s); /* Workaround: Need to write PP_CONTROL with the unlock key as @@ -4795,35 +4786,52 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, pp_on = I915_READ(regs.pp_on); pp_off = I915_READ(regs.pp_off); - if (!IS_BROXTON(dev)) { + if (!IS_BROXTON(dev_priv)) { I915_WRITE(regs.pp_ctrl, pp_ctl); pp_div = I915_READ(regs.pp_div); } /* Pull timing values out of registers */ - cur.t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >> - PANEL_POWER_UP_DELAY_SHIFT; + seq->t1_t3 = (pp_on & PANEL_POWER_UP_DELAY_MASK) >> + PANEL_POWER_UP_DELAY_SHIFT; - cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> - PANEL_LIGHT_ON_DELAY_SHIFT; + seq->t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> + PANEL_LIGHT_ON_DELAY_SHIFT; - cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> - PANEL_LIGHT_OFF_DELAY_SHIFT; + seq->t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> + PANEL_LIGHT_OFF_DELAY_SHIFT; - cur.t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >> - PANEL_POWER_DOWN_DELAY_SHIFT; + seq->t10 = (pp_off & PANEL_POWER_DOWN_DELAY_MASK) >> + PANEL_POWER_DOWN_DELAY_SHIFT; - if (IS_BROXTON(dev)) { + if (IS_BROXTON(dev_priv)) { u16 tmp = (pp_ctl & BXT_POWER_CYCLE_DELAY_MASK) >> BXT_POWER_CYCLE_DELAY_SHIFT; if (tmp > 0) - cur.t11_t12 = (tmp - 1) * 1000; + seq->t11_t12 = (tmp - 1) * 1000; else - cur.t11_t12 = 0; + seq->t11_t12 = 0; } else { - cur.t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >> + seq->t11_t12 = ((pp_div & PANEL_POWER_CYCLE_DELAY_MASK) >> PANEL_POWER_CYCLE_DELAY_SHIFT) * 1000; } +} + +static void +intel_dp_init_panel_power_sequencer(struct drm_device *dev, + struct intel_dp *intel_dp) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct edp_power_seq cur, vbt, spec, + *final = &intel_dp->pps_delays; + + lockdep_assert_held(&dev_priv->pps_mutex); + + /* already initialized? */ + if (final->t11_t12 != 0) + return; + + intel_pps_readout_hw_state(dev_priv, intel_dp, &cur); DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12); -- cgit v1.2.3 From de9c1b6b088ca2795594ff58e1778de668821db3 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 16 Jun 2016 20:01:46 +0300 Subject: drm/i915: Sanity check PPS HW state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wait for panel status helper will only function correctly if the HW panel timings are programmed correctly. Returning prematurely from this helper may lead to obscure bugs later, so sanity check the HW timing registers. v2: - Check the T8, T9 fields too, we do program them (Ville) CC: Ville Syrjälä Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1466096506-11937-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 58 +++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6992915f8642..9a1a347146dd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1772,6 +1772,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder) #define IDLE_CYCLE_MASK (PP_ON | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK) #define IDLE_CYCLE_VALUE (0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) +static void intel_pps_verify_state(struct drm_i915_private *dev_priv, + struct intel_dp *intel_dp); + static void wait_panel_status(struct intel_dp *intel_dp, u32 mask, u32 value) @@ -1782,6 +1785,8 @@ static void wait_panel_status(struct intel_dp *intel_dp, lockdep_assert_held(&dev_priv->pps_mutex); + intel_pps_verify_state(dev_priv, intel_dp); + pp_stat_reg = _pp_stat_reg(intel_dp); pp_ctrl_reg = _pp_ctrl_reg(intel_dp); @@ -4817,6 +4822,31 @@ intel_pps_readout_hw_state(struct drm_i915_private *dev_priv, } } +static void +intel_pps_dump_state(const char *state_name, const struct edp_power_seq *seq) +{ + DRM_DEBUG_KMS("%s t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", + state_name, + seq->t1_t3, seq->t8, seq->t9, seq->t10, seq->t11_t12); +} + +static void +intel_pps_verify_state(struct drm_i915_private *dev_priv, + struct intel_dp *intel_dp) +{ + struct edp_power_seq hw; + struct edp_power_seq *sw = &intel_dp->pps_delays; + + intel_pps_readout_hw_state(dev_priv, intel_dp, &hw); + + if (hw.t1_t3 != sw->t1_t3 || hw.t8 != sw->t8 || hw.t9 != sw->t9 || + hw.t10 != sw->t10 || hw.t11_t12 != sw->t11_t12) { + DRM_ERROR("PPS state mismatch\n"); + intel_pps_dump_state("sw", sw); + intel_pps_dump_state("hw", &hw); + } +} + static void intel_dp_init_panel_power_sequencer(struct drm_device *dev, struct intel_dp *intel_dp) @@ -4833,8 +4863,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, intel_pps_readout_hw_state(dev_priv, intel_dp, &cur); - DRM_DEBUG_KMS("cur t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", - cur.t1_t3, cur.t8, cur.t9, cur.t10, cur.t11_t12); + intel_pps_dump_state("cur", &cur); vbt = dev_priv->vbt.edp.pps; @@ -4850,8 +4879,7 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, * too. */ spec.t11_t12 = (510 + 100) * 10; - DRM_DEBUG_KMS("vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n", - vbt.t1_t3, vbt.t8, vbt.t9, vbt.t10, vbt.t11_t12); + intel_pps_dump_state("vbt", &vbt); /* Use the max of the register settings and vbt. If both are * unset, fall back to the spec limits. */ @@ -4879,6 +4907,16 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev, DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); + + /* + * We override the HW backlight delays to 1 because we do manual waits + * on them. For T8, even BSpec recommends doing it. For T9, if we + * don't do this, we'll end up waiting for the backlight off delay + * twice: once when we do the manual sleep, and once when we disable + * the panel and wait for the PP_STATUS bit to become zero. + */ + final->t8 = 1; + final->t9 = 1; } static void @@ -4896,17 +4934,9 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, intel_pps_get_registers(dev_priv, intel_dp, ®s); - /* - * And finally store the new values in the power sequencer. The - * backlight delays are set to 1 because we do manual waits on them. For - * T8, even BSpec recommends doing it. For T9, if we don't do this, - * we'll end up waiting for the backlight off delay twice: once when we - * do the manual sleep, and once when we disable the panel and wait for - * the PP_STATUS bit to become zero. - */ pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | - (1 << PANEL_LIGHT_ON_DELAY_SHIFT); - pp_off = (1 << PANEL_LIGHT_OFF_DELAY_SHIFT) | + (seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT); + pp_off = (seq->t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) | (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT); /* Compute the divisor for the pp clock, simply match the Bspec * formula. */ -- cgit v1.2.3 From 64989ca4b27acb026b6496ec21e43bee66f86a5b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 13 May 2016 20:53:56 +0300 Subject: drm/i915: Refresh cached DP port register value on resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During hibernation the cached DP port register value will be left with whatever value we have there when we create the hibernation image. Currently that means the port (and eDP PLL) will be off in the cached value. However when we resume there is no guarantee that the value in the actual register will match the cached value. If i915 isn't loaded in the kernel that loads the hibernation image, the port may well be on (eg. left on by the BIOS). The encoder state readout does the right thing in this case and updates our encoder state to reflect the actual hardware state. However the post-resume modeset will then use the stale cached port register value in intel_dp_link_down() and potentially confuse the hardware. This was caught by the following assert WARNING: CPU: 3 PID: 5288 at ../drivers/gpu/drm/i915/intel_dp.c:2184 assert_edp_pll+0x99/0xa0 [i915] eDP PLL state assertion failure (expected on, current off) on account of the eDP PLL getting prematurely turned off when shutting down the port, since the DP_PLL_ENABLE bit wasn't set in the cached register value. Presumably I introduced this problem in commit 6fec76628333 ("drm/i915: Use intel_dp->DP in eDP PLL setup") as before that we didn't update the cached value after shuttting the port down. That's assuming the port got enabled at least once prior to hibernating. If that didn't happen then the cached value would still have been totally out of sync with reality (eg. first boot w/o eDP on, then hibernate, and then resume with eDP on). So, let's fix this properly and refresh the cached register value from the hardware register during resume. DDI platforms shouldn't use the cached value during port disable at least, so shouldn't have this particular issue. They might still have issues if we skip the initial modeset and then try to retrain the link or something. But untangling this DP vs. DDI mess is a bigger topic, so let's jut punt on DDI for now. Cc: Jani Nikula Cc: stable@vger.kernel.org Fixes: 6fec76628333 ("drm/i915: Use intel_dp->DP in eDP PLL setup") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/1463162036-27931-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_dp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 9a1a347146dd..8bb20e7048ec 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4618,13 +4618,15 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) void intel_dp_encoder_reset(struct drm_encoder *encoder) { - struct intel_dp *intel_dp; + struct drm_i915_private *dev_priv = to_i915(encoder->dev); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + if (!HAS_DDI(dev_priv)) + intel_dp->DP = I915_READ(intel_dp->output_reg); if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP) return; - intel_dp = enc_to_intel_dp(encoder); - pps_lock(intel_dp); /* -- cgit v1.2.3 From a19d6ff29a825418f1407dfb1c909648db057924 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 23 Jun 2016 14:52:41 +0100 Subject: drm/i915: Small compaction of the engine init code Effectively removes one layer of indirection between the mask of possible engines and the engine constructors. Instead of spelling out in code the mapping of HAS_ to constructors, makes more use of the recently added data driven approach by putting engine constructor vfuncs into the table as well. Effect is fewer lines of source and smaller binary. At the same time simplify the error handling since engine destructors can run on unitialized engines anyway. Similar approach could be done for legacy submission is wanted. v2: Removed ugly BUILD_BUG_ONs in favour of newly introduced ENGINE_MASK and HAS_ENGINE macros. Also removed the forward declarations by shuffling functions around. v3: Warn when logical_rings table does not contain enough data and disable the engines which could not be initialized. (Chris Wilson) v4: Chris Wilson suggested a nicer engine init loop. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1466689961-23232-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 27 +++-- drivers/gpu/drm/i915/intel_lrc.c | 253 ++++++++++++++++++--------------------- 2 files changed, 130 insertions(+), 150 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 74d0a61de75a..6d96b14b53c8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2759,17 +2759,22 @@ struct drm_i915_cmd_table { #define IS_GEN8(dev) (INTEL_INFO(dev)->gen_mask & BIT(7)) #define IS_GEN9(dev) (INTEL_INFO(dev)->gen_mask & BIT(8)) -#define RENDER_RING (1<ring_mask & BSD_RING) -#define HAS_BSD2(dev) (INTEL_INFO(dev)->ring_mask & BSD2_RING) -#define HAS_BLT(dev) (INTEL_INFO(dev)->ring_mask & BLT_RING) -#define HAS_VEBOX(dev) (INTEL_INFO(dev)->ring_mask & VEBOX_RING) +#define ENGINE_MASK(id) BIT(id) +#define RENDER_RING ENGINE_MASK(RCS) +#define BSD_RING ENGINE_MASK(VCS) +#define BLT_RING ENGINE_MASK(BCS) +#define VEBOX_RING ENGINE_MASK(VECS) +#define BSD2_RING ENGINE_MASK(VCS2) +#define ALL_ENGINES (~0) + +#define HAS_ENGINE(dev_priv, id) \ + (INTEL_INFO(dev_priv)->ring_mask & ENGINE_MASK(id)) + +#define HAS_BSD(dev_priv) HAS_ENGINE(dev_priv, VCS) +#define HAS_BSD2(dev_priv) HAS_ENGINE(dev_priv, VCS2) +#define HAS_BLT(dev_priv) HAS_ENGINE(dev_priv, BCS) +#define HAS_VEBOX(dev_priv) HAS_ENGINE(dev_priv, VECS) + #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define HAS_SNOOP(dev) (INTEL_INFO(dev)->has_snoop) #define HAS_EDRAM(dev) (__I915__(dev)->edram_cap & EDRAM_ENABLED) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index debed011a958..62b0dc6c2642 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2016,12 +2016,90 @@ lrc_setup_hws(struct intel_engine_cs *engine, return 0; } +static int +logical_ring_init(struct intel_engine_cs *engine) +{ + struct i915_gem_context *dctx = engine->i915->kernel_context; + int ret; + + ret = i915_cmd_parser_init_ring(engine); + if (ret) + goto error; + + ret = execlists_context_deferred_alloc(dctx, engine); + if (ret) + goto error; + + /* As this is the default context, always pin it */ + ret = intel_lr_context_pin(dctx, engine); + if (ret) { + DRM_ERROR("Failed to pin context for %s: %d\n", + engine->name, ret); + goto error; + } + + /* And setup the hardware status page. */ + ret = lrc_setup_hws(engine, dctx->engine[engine->id].state); + if (ret) { + DRM_ERROR("Failed to set up hws %s: %d\n", engine->name, ret); + goto error; + } + + return 0; + +error: + intel_logical_ring_cleanup(engine); + return ret; +} + +static int logical_render_ring_init(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + int ret; + + if (HAS_L3_DPF(dev_priv)) + engine->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; + + /* Override some for render ring. */ + if (INTEL_GEN(dev_priv) >= 9) + engine->init_hw = gen9_init_render_ring; + else + engine->init_hw = gen8_init_render_ring; + engine->init_context = gen8_init_rcs_context; + engine->cleanup = intel_fini_pipe_control; + engine->emit_flush = gen8_emit_flush_render; + engine->emit_request = gen8_emit_request_render; + + ret = intel_init_pipe_control(engine); + if (ret) + return ret; + + ret = intel_init_workaround_bb(engine); + if (ret) { + /* + * We continue even if we fail to initialize WA batch + * because we only expect rare glitches but nothing + * critical to prevent us from using GPU + */ + DRM_ERROR("WA batch buffer initialization failed: %d\n", + ret); + } + + ret = logical_ring_init(engine); + if (ret) { + lrc_destroy_wa_ctx_obj(engine); + } + + return ret; +} + static const struct logical_ring_info { const char *name; unsigned exec_id; unsigned guc_id; u32 mmio_base; unsigned irq_shift; + int (*init)(struct intel_engine_cs *engine); } logical_rings[] = { [RCS] = { .name = "render ring", @@ -2029,6 +2107,7 @@ static const struct logical_ring_info { .guc_id = GUC_RENDER_ENGINE, .mmio_base = RENDER_RING_BASE, .irq_shift = GEN8_RCS_IRQ_SHIFT, + .init = logical_render_ring_init, }, [BCS] = { .name = "blitter ring", @@ -2036,6 +2115,7 @@ static const struct logical_ring_info { .guc_id = GUC_BLITTER_ENGINE, .mmio_base = BLT_RING_BASE, .irq_shift = GEN8_BCS_IRQ_SHIFT, + .init = logical_ring_init, }, [VCS] = { .name = "bsd ring", @@ -2043,6 +2123,7 @@ static const struct logical_ring_info { .guc_id = GUC_VIDEO_ENGINE, .mmio_base = GEN6_BSD_RING_BASE, .irq_shift = GEN8_VCS1_IRQ_SHIFT, + .init = logical_ring_init, }, [VCS2] = { .name = "bsd2 ring", @@ -2050,6 +2131,7 @@ static const struct logical_ring_info { .guc_id = GUC_VIDEO_ENGINE2, .mmio_base = GEN8_BSD2_RING_BASE, .irq_shift = GEN8_VCS2_IRQ_SHIFT, + .init = logical_ring_init, }, [VECS] = { .name = "video enhancement ring", @@ -2057,14 +2139,14 @@ static const struct logical_ring_info { .guc_id = GUC_VIDEOENHANCE_ENGINE, .mmio_base = VEBOX_RING_BASE, .irq_shift = GEN8_VECS_IRQ_SHIFT, + .init = logical_ring_init, }, }; static struct intel_engine_cs * -logical_ring_setup(struct drm_device *dev, enum intel_engine_id id) +logical_ring_setup(struct drm_i915_private *dev_priv, enum intel_engine_id id) { const struct logical_ring_info *info = &logical_rings[id]; - struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine = &dev_priv->engine[id]; enum forcewake_domains fw_domains; @@ -2107,169 +2189,62 @@ logical_ring_setup(struct drm_device *dev, enum intel_engine_id id) logical_ring_default_irqs(engine, info->irq_shift); intel_engine_init_hangcheck(engine); - i915_gem_batch_pool_init(dev, &engine->batch_pool); + i915_gem_batch_pool_init(dev_priv->dev, &engine->batch_pool); return engine; } -static int -logical_ring_init(struct intel_engine_cs *engine) -{ - struct i915_gem_context *dctx = engine->i915->kernel_context; - int ret; - - ret = i915_cmd_parser_init_ring(engine); - if (ret) - goto error; - - ret = execlists_context_deferred_alloc(dctx, engine); - if (ret) - goto error; - - /* As this is the default context, always pin it */ - ret = intel_lr_context_pin(dctx, engine); - if (ret) { - DRM_ERROR("Failed to pin context for %s: %d\n", - engine->name, ret); - goto error; - } - - /* And setup the hardware status page. */ - ret = lrc_setup_hws(engine, dctx->engine[engine->id].state); - if (ret) { - DRM_ERROR("Failed to set up hws %s: %d\n", engine->name, ret); - goto error; - } - - return 0; - -error: - intel_logical_ring_cleanup(engine); - return ret; -} - -static int logical_render_ring_init(struct drm_device *dev) -{ - struct intel_engine_cs *engine = logical_ring_setup(dev, RCS); - int ret; - - if (HAS_L3_DPF(dev)) - engine->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; - - /* Override some for render ring. */ - if (INTEL_INFO(dev)->gen >= 9) - engine->init_hw = gen9_init_render_ring; - else - engine->init_hw = gen8_init_render_ring; - engine->init_context = gen8_init_rcs_context; - engine->cleanup = intel_fini_pipe_control; - engine->emit_flush = gen8_emit_flush_render; - engine->emit_request = gen8_emit_request_render; - - ret = intel_init_pipe_control(engine); - if (ret) - return ret; - - ret = intel_init_workaround_bb(engine); - if (ret) { - /* - * We continue even if we fail to initialize WA batch - * because we only expect rare glitches but nothing - * critical to prevent us from using GPU - */ - DRM_ERROR("WA batch buffer initialization failed: %d\n", - ret); - } - - ret = logical_ring_init(engine); - if (ret) { - lrc_destroy_wa_ctx_obj(engine); - } - - return ret; -} - -static int logical_bsd_ring_init(struct drm_device *dev) -{ - struct intel_engine_cs *engine = logical_ring_setup(dev, VCS); - - return logical_ring_init(engine); -} - -static int logical_bsd2_ring_init(struct drm_device *dev) -{ - struct intel_engine_cs *engine = logical_ring_setup(dev, VCS2); - - return logical_ring_init(engine); -} - -static int logical_blt_ring_init(struct drm_device *dev) -{ - struct intel_engine_cs *engine = logical_ring_setup(dev, BCS); - - return logical_ring_init(engine); -} - -static int logical_vebox_ring_init(struct drm_device *dev) -{ - struct intel_engine_cs *engine = logical_ring_setup(dev, VECS); - - return logical_ring_init(engine); -} - /** * intel_logical_rings_init() - allocate, populate and init the Engine Command Streamers * @dev: DRM device. * - * This function inits the engines for an Execlists submission style (the equivalent in the - * legacy ringbuffer submission world would be i915_gem_init_engines). It does it only for - * those engines that are present in the hardware. + * This function inits the engines for an Execlists submission style (the + * equivalent in the legacy ringbuffer submission world would be + * i915_gem_init_engines). It does it only for those engines that are present in + * the hardware. * * Return: non-zero if the initialization failed. */ int intel_logical_rings_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + unsigned int mask = 0; + unsigned int i; int ret; - ret = logical_render_ring_init(dev); - if (ret) - return ret; + WARN_ON(INTEL_INFO(dev_priv)->ring_mask & + GENMASK(sizeof(mask) * BITS_PER_BYTE - 1, I915_NUM_ENGINES)); - if (HAS_BSD(dev)) { - ret = logical_bsd_ring_init(dev); - if (ret) - goto cleanup_render_ring; - } + for (i = 0; i < ARRAY_SIZE(logical_rings); i++) { + if (!HAS_ENGINE(dev_priv, i)) + continue; - if (HAS_BLT(dev)) { - ret = logical_blt_ring_init(dev); - if (ret) - goto cleanup_bsd_ring; - } + if (!logical_rings[i].init) + continue; - if (HAS_VEBOX(dev)) { - ret = logical_vebox_ring_init(dev); + ret = logical_rings[i].init(logical_ring_setup(dev_priv, i)); if (ret) - goto cleanup_blt_ring; + goto cleanup; + + mask |= ENGINE_MASK(i); } - if (HAS_BSD2(dev)) { - ret = logical_bsd2_ring_init(dev); - if (ret) - goto cleanup_vebox_ring; + /* + * Catch failures to update logical_rings table when the new engines + * are added to the driver by a warning and disabling the forgotten + * engines. + */ + if (WARN_ON(mask != INTEL_INFO(dev_priv)->ring_mask)) { + struct intel_device_info *info = + (struct intel_device_info *)&dev_priv->info; + info->ring_mask = mask; } return 0; -cleanup_vebox_ring: - intel_logical_ring_cleanup(&dev_priv->engine[VECS]); -cleanup_blt_ring: - intel_logical_ring_cleanup(&dev_priv->engine[BCS]); -cleanup_bsd_ring: - intel_logical_ring_cleanup(&dev_priv->engine[VCS]); -cleanup_render_ring: - intel_logical_ring_cleanup(&dev_priv->engine[RCS]); +cleanup: + for (i = 0; i < I915_NUM_ENGINES; i++) + intel_logical_ring_cleanup(&dev_priv->engine[i]); return ret; } -- cgit v1.2.3 From fda9ee98230cd4799cddaede37ab3051ac7645df Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:13 +0100 Subject: drm/i915: Move panel's backlight setup next to panel init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently setting up the backlight for a panel is sometimes done together with initialising the panel, and sometimes after the connector is registered. The backlight setup does not depend upon connector registration (i.e. access to sysfs/debugfs and the kobject hierachy) so perform it consistently just after panel initialisation. Note the discrepancy here as destroying the panel is done during connector unregistration... Signed-off-by: Chris Wilson Cc: Jani Nikula Cc: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_drv.h | 3 ++- drivers/gpu/drm/i915/intel_dsi.c | 3 +-- drivers/gpu/drm/i915/intel_lvds.c | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1f82dccfcd58..ca2de043b9ce 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1496,7 +1496,8 @@ void intel_gmch_panel_fitting(struct intel_crtc *crtc, int fitting_mode); void intel_panel_set_backlight_acpi(struct intel_connector *connector, u32 level, u32 max); -int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe); +int intel_panel_setup_backlight(struct drm_connector *connector, + enum pipe pipe); void intel_panel_enable_backlight(struct intel_connector *connector); void intel_panel_disable_backlight(struct intel_connector *connector); void intel_panel_destroy_backlight(struct drm_connector *connector); diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index b444d0e35a98..ae2dcaf1b52e 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1587,13 +1587,12 @@ void intel_dsi_init(struct drm_device *dev) connector->display_info.height_mm = fixed_mode->height_mm; intel_panel_init(&intel_connector->panel, fixed_mode, NULL); + intel_panel_setup_backlight(connector, INVALID_PIPE); intel_dsi_add_properties(intel_connector); drm_connector_register(connector); - intel_panel_setup_backlight(connector, INVALID_PIPE); - return; err: diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 935b53642948..6306c5499587 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -1120,6 +1120,7 @@ out: mutex_unlock(&dev->mode_config.mutex); intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); + intel_panel_setup_backlight(connector, INVALID_PIPE); lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); DRM_DEBUG_KMS("detected %s-link lvds configuration\n", @@ -1134,8 +1135,6 @@ out: } drm_connector_register(connector); - intel_panel_setup_backlight(connector, INVALID_PIPE); - return; failed: -- cgit v1.2.3 From 7a418e3448f8c47fb44cc995d7983e735b9774c7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:14 +0100 Subject: drm/i915: Move registration actions to connector->late_register With the introduction of a connector->func for callback from drm_connector_register() we can move all the tasks that we want to do upon registration into that callback. Later, this will allow us to reorder the registration and defer it until after the device is setup and ready for userspace. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dp.c | 48 ++++++++++++++++--------------------- drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ drivers/gpu/drm/i915/intel_sdvo.c | 19 ++++++++------- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 85f2801b16ed..d4e037e20fa1 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1249,35 +1249,18 @@ intel_dp_aux_fini(struct intel_dp *intel_dp) kfree(intel_dp->aux.name); } -static int +static void intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); enum port port = intel_dig_port->port; - int ret; intel_aux_reg_init(intel_dp); + drm_dp_aux_init(&intel_dp->aux); + /* Failure to allocate our preferred name is not critical */ intel_dp->aux.name = kasprintf(GFP_KERNEL, "DPDDC-%c", port_name(port)); - if (!intel_dp->aux.name) - return -ENOMEM; - - intel_dp->aux.dev = connector->base.kdev; intel_dp->aux.transfer = intel_dp_aux_transfer; - - DRM_DEBUG_KMS("registering %s bus for %s\n", - intel_dp->aux.name, - connector->base.kdev->kobj.name); - - ret = drm_dp_aux_register(&intel_dp->aux); - if (ret < 0) { - DRM_ERROR("drm_dp_aux_register() for %s failed (%d)\n", - intel_dp->aux.name, ret); - kfree(intel_dp->aux.name); - return ret; - } - - return 0; } static int @@ -4520,6 +4503,20 @@ done: return 0; } +static int +intel_dp_connector_register(struct drm_connector *connector) +{ + struct intel_dp *intel_dp = intel_attached_dp(connector); + + i915_debugfs_connector_add(connector); + + DRM_DEBUG_KMS("registering %s bus for %s\n", + intel_dp->aux.name, connector->kdev->kobj.name); + + intel_dp->aux.dev = connector->kdev; + return drm_dp_aux_register(&intel_dp->aux); +} + static void intel_dp_connector_unregister(struct drm_connector *connector) { @@ -4648,6 +4645,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .set_property = intel_dp_set_property, .atomic_get_property = intel_connector_atomic_get_property, + .late_register = intel_dp_connector_register, .early_unregister = intel_dp_connector_unregister, .destroy = intel_dp_connector_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, @@ -5515,7 +5513,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; enum port port = intel_dig_port->port; - int type, ret; + int type; if (WARN(intel_dig_port->max_lanes < 1, "Not enough lanes (%d) for DP on port %c\n", @@ -5574,6 +5572,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, connector->interlace_allowed = true; connector->doublescan_allowed = 0; + intel_dp_aux_init(intel_dp, intel_connector); + INIT_DELAYED_WORK(&intel_dp->panel_vdd_work, edp_panel_vdd_work); @@ -5608,10 +5608,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, BUG(); } - ret = intel_dp_aux_init(intel_dp, intel_connector); - if (ret) - goto fail; - /* init MST on ports that can support it */ if (HAS_DP_MST(dev) && (port == PORT_B || port == PORT_C || port == PORT_D)) @@ -5635,8 +5631,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); } - i915_debugfs_connector_add(connector); - return true; fail: diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 9646816604be..89e7c98f5693 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -477,9 +477,11 @@ static void intel_dp_register_mst_connector(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_device *dev = connector->dev; + drm_modeset_lock_all(dev); intel_connector_add_to_fbdev(intel_connector); drm_modeset_unlock_all(dev); + drm_connector_register(&intel_connector->base); } diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 02b4a6695528..580cc876a90f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2177,6 +2177,16 @@ done: #undef CHECK_PROPERTY } +static int +intel_sdvo_connector_register(struct drm_connector *connector) +{ + struct intel_sdvo *sdvo = intel_attached_sdvo(connector); + + return sysfs_create_link(&connector->kdev->kobj, + &sdvo->ddc.dev.kobj, + sdvo->ddc.dev.kobj.name); +} + static void intel_sdvo_connector_unregister(struct drm_connector *connector) { @@ -2193,6 +2203,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .set_property = intel_sdvo_set_property, .atomic_get_property = intel_connector_atomic_get_property, + .late_register = intel_sdvo_connector_register, .early_unregister = intel_sdvo_connector_unregister, .destroy = intel_sdvo_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, @@ -2384,16 +2395,8 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, if (ret < 0) goto err1; - ret = sysfs_create_link(&drm_connector->kdev->kobj, - &encoder->ddc.dev.kobj, - encoder->ddc.dev.kobj.name); - if (ret < 0) - goto err2; - return 0; -err2: - drm_connector_unregister(drm_connector); err1: drm_connector_cleanup(drm_connector); -- cgit v1.2.3 From 1ebaa0b9c2d47ddc832a74254beaa518f64b9cb4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:15 +0100 Subject: drm/i915: Move backlight registration to connector registration Currently the backlight is being registered in the load phase (before the display and its objects are registered). Move the backlight registration into the analogous phase by performing it from the connector registration, just after its creation. Signed-off-by: Chris Wilson Cc: Jani Nikula Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-3-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_crt.c | 1 + drivers/gpu/drm/i915/intel_display.c | 15 ++++++++++++++- drivers/gpu/drm/i915/intel_dp.c | 5 +++++ drivers/gpu/drm/i915/intel_dp_mst.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 6 +++++- drivers/gpu/drm/i915/intel_dsi.c | 1 + drivers/gpu/drm/i915/intel_dvo.c | 1 + drivers/gpu/drm/i915/intel_hdmi.c | 1 + drivers/gpu/drm/i915/intel_lvds.c | 1 + drivers/gpu/drm/i915/intel_panel.c | 15 +-------------- drivers/gpu/drm/i915/intel_sdvo.c | 5 +++++ drivers/gpu/drm/i915/intel_tv.c | 1 + 13 files changed, 38 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6d96b14b53c8..42298a87db7e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3734,6 +3734,7 @@ extern void intel_modeset_init_hw(struct drm_device *dev); extern void intel_modeset_init(struct drm_device *dev); extern void intel_modeset_gem_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); +extern int intel_connector_register(struct drm_connector *); extern void intel_connector_unregister(struct drm_connector *); extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); extern void intel_display_resume(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index e115bcc6766f..8d7d48c74751 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -743,6 +743,7 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .detect = intel_crt_detect, .fill_modes = drm_helper_probe_single_connector_modes, + .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_crt_destroy, .set_property = intel_crt_set_property, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1141b8699dbe..12897d11df60 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -16314,8 +16314,21 @@ void intel_modeset_gem_init(struct drm_device *dev) c->state->plane_mask &= ~(1 << drm_plane_index(c->primary)); } } +} + +int intel_connector_register(struct drm_connector *connector) +{ + struct intel_connector *intel_connector = to_intel_connector(connector); + int ret; + + ret = intel_backlight_device_register(intel_connector); + if (ret) + goto err; + + return 0; - intel_backlight_register(dev); +err: + return ret; } void intel_connector_unregister(struct drm_connector *connector) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d4e037e20fa1..30d410173816 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4507,6 +4507,11 @@ static int intel_dp_connector_register(struct drm_connector *connector) { struct intel_dp *intel_dp = intel_attached_dp(connector); + int ret; + + ret = intel_connector_register(connector); + if (ret) + return ret; i915_debugfs_connector_add(connector); diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 89e7c98f5693..5f88e12575ac 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -336,6 +336,7 @@ static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .set_property = intel_dp_mst_set_property, .atomic_get_property = intel_connector_atomic_get_property, + .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_dp_mst_connector_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ca2de043b9ce..3156d8df7921 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1506,11 +1506,15 @@ extern struct drm_display_mode *intel_find_panel_downclock( struct drm_device *dev, struct drm_display_mode *fixed_mode, struct drm_connector *connector); -void intel_backlight_register(struct drm_device *dev); #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) +int intel_backlight_device_register(struct intel_connector *connector); void intel_backlight_device_unregister(struct intel_connector *connector); #else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ +static int intel_backlight_device_register(struct intel_connector *connector) +{ + return 0; +} static inline void intel_backlight_device_unregister(struct intel_connector *connector) { } diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index ae2dcaf1b52e..80cc0f9de6c9 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1390,6 +1390,7 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs static const struct drm_connector_funcs intel_dsi_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .detect = intel_dsi_detect, + .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_dsi_connector_destroy, .fill_modes = drm_helper_probe_single_connector_modes, diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 60e4ddf2ec6d..669eae46ffa9 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -341,6 +341,7 @@ static void intel_dvo_destroy(struct drm_connector *connector) static const struct drm_connector_funcs intel_dvo_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .detect = intel_dvo_detect, + .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_dvo_destroy, .fill_modes = drm_helper_probe_single_connector_modes, diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index fb21626ada64..48ca48c9faff 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1774,6 +1774,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .set_property = intel_hdmi_set_property, .atomic_get_property = intel_connector_atomic_get_property, + .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_hdmi_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 6306c5499587..d4d06fb8de2e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -555,6 +555,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .set_property = intel_lvds_set_property, .atomic_get_property = intel_connector_atomic_get_property, + .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_lvds_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index bf721781c259..3c0b97f0bfae 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1163,7 +1163,7 @@ static const struct backlight_ops intel_backlight_device_ops = { .get_brightness = intel_backlight_device_get_brightness, }; -static int intel_backlight_device_register(struct intel_connector *connector) +int intel_backlight_device_register(struct intel_connector *connector) { struct intel_panel *panel = &connector->panel; struct backlight_properties props; @@ -1225,11 +1225,6 @@ void intel_backlight_device_unregister(struct intel_connector *connector) panel->backlight.device = NULL; } } -#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ -static int intel_backlight_device_register(struct intel_connector *connector) -{ - return 0; -} #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ /* @@ -1809,11 +1804,3 @@ void intel_panel_fini(struct intel_panel *panel) drm_mode_destroy(intel_connector->base.dev, panel->downclock_mode); } - -void intel_backlight_register(struct drm_device *dev) -{ - struct intel_connector *connector; - - for_each_intel_connector(dev, connector) - intel_backlight_device_register(connector); -} diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 580cc876a90f..c0c0a65fabf3 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2181,6 +2181,11 @@ static int intel_sdvo_connector_register(struct drm_connector *connector) { struct intel_sdvo *sdvo = intel_attached_sdvo(connector); + int ret; + + ret = intel_connector_register(connector); + if (ret) + return ret; return sysfs_create_link(&connector->kdev->kobj, &sdvo->ddc.dev.kobj, diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 4ce70a9f9df2..83fe6706a188 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1501,6 +1501,7 @@ out: static const struct drm_connector_funcs intel_tv_connector_funcs = { .dpms = drm_atomic_helper_connector_dpms, .detect = intel_tv_detect, + .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_tv_destroy, .set_property = intel_tv_set_property, -- cgit v1.2.3 From 843152b4b9866a1a3b9db4d866cc6e99b10f7e57 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:16 +0100 Subject: drm/i915: Move connector registration to driver registration Defer connector registration from during construction to the driver registration phase. This is important for ordering the action correctly, e.g. not using debugfs before it is ready. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-4-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_dma.c | 2 ++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_crt.c | 2 -- drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++-- drivers/gpu/drm/i915/intel_dp.c | 2 -- drivers/gpu/drm/i915/intel_dsi.c | 2 -- drivers/gpu/drm/i915/intel_dvo.c | 1 - drivers/gpu/drm/i915/intel_hdmi.c | 1 - drivers/gpu/drm/i915/intel_lvds.c | 1 - drivers/gpu/drm/i915/intel_sdvo.c | 10 ---------- drivers/gpu/drm/i915/intel_tv.c | 1 - 11 files changed, 14 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e28c0ddc0837..29521c4b87a5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1398,6 +1398,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); i915_setup_sysfs(dev); + intel_modeset_register(dev_priv); if (INTEL_INFO(dev_priv)->num_pipes) { /* Must be done after probing outputs */ @@ -1430,6 +1431,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) intel_gpu_ips_teardown(); acpi_video_unregister(); intel_opregion_unregister(dev_priv); + intel_modeset_unregister(dev_priv); i915_teardown_sysfs(dev_priv->dev); i915_gem_shrinker_cleanup(dev_priv); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 42298a87db7e..73683b54da7a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3734,6 +3734,8 @@ extern void intel_modeset_init_hw(struct drm_device *dev); extern void intel_modeset_init(struct drm_device *dev); extern void intel_modeset_gem_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); +extern void intel_modeset_register(struct drm_i915_private *dev_priv); +extern void intel_modeset_unregister(struct drm_i915_private *dev_priv); extern int intel_connector_register(struct drm_connector *); extern void intel_connector_unregister(struct drm_connector *); extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 8d7d48c74751..165e4b901548 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -880,8 +880,6 @@ void intel_crt_init(struct drm_device *dev) drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); - drm_connector_register(connector); - if (!I915_HAS_HOTPLUG(dev)) intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 12897d11df60..798c175c37bf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15551,6 +15551,16 @@ void intel_modeset_init_hw(struct drm_device *dev) intel_enable_gt_powersave(dev_priv); } +void intel_modeset_register(struct drm_i915_private *dev_priv) +{ + drm_connector_register_all(dev_priv->dev); +} + +void intel_modeset_unregister(struct drm_i915_private *dev_priv) +{ + drm_connector_unregister_all(dev_priv->dev); +} + /* * Calculate what we think the watermarks should be for the state we've read * out of the hardware and then immediately program those watermarks so that @@ -16365,8 +16375,6 @@ void intel_modeset_cleanup(struct drm_device *dev) /* flush any delayed tasks or pending work */ flush_scheduled_work(); - drm_connector_unregister_all(dev); - drm_mode_config_cleanup(dev); intel_cleanup_overlay(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 30d410173816..c3742a04f611 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5583,7 +5583,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, edp_panel_vdd_work); intel_connector_attach_encoder(intel_connector, intel_encoder); - drm_connector_register(connector); if (HAS_DDI(dev)) intel_connector->get_hw_state = intel_ddi_connector_get_hw_state; @@ -5639,7 +5638,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, return true; fail: - drm_connector_unregister(connector); drm_connector_cleanup(connector); return false; diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 80cc0f9de6c9..63b720061bd2 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1592,8 +1592,6 @@ void intel_dsi_init(struct drm_device *dev) intel_dsi_add_properties(intel_connector); - drm_connector_register(connector); - return; err: diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 669eae46ffa9..14b1d3f333a4 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -551,7 +551,6 @@ void intel_dvo_init(struct drm_device *dev) intel_dvo->panel_wants_dither = true; } - drm_connector_register(connector); return; } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 48ca48c9faff..86e1fdb70141 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1915,7 +1915,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, intel_hdmi_add_properties(intel_hdmi, connector); intel_connector_attach_encoder(intel_connector, intel_encoder); - drm_connector_register(connector); intel_hdmi->attached_connector = intel_connector; /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index d4d06fb8de2e..cf680661454b 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -1134,7 +1134,6 @@ out: DRM_DEBUG_KMS("lid notifier registration failed\n"); lvds_connector->lid_notifier.notifier_call = NULL; } - drm_connector_register(connector); return; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c0c0a65fabf3..ba28f5141687 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2396,16 +2396,8 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, connector->base.get_hw_state = intel_sdvo_connector_get_hw_state; intel_connector_attach_encoder(&connector->base, &encoder->base); - ret = drm_connector_register(drm_connector); - if (ret < 0) - goto err1; return 0; - -err1: - drm_connector_cleanup(drm_connector); - - return ret; } static void @@ -2532,7 +2524,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) return true; err: - drm_connector_unregister(connector); intel_sdvo_destroy(connector); return false; } @@ -2611,7 +2602,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) return true; err: - drm_connector_unregister(connector); intel_sdvo_destroy(connector); return false; } diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 83fe6706a188..153190475ebd 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1642,5 +1642,4 @@ intel_tv_init(struct drm_device *dev) drm_object_attach_property(&connector->base, dev->mode_config.tv_bottom_margin_property, intel_tv->margin[TV_MARGIN_BOTTOM]); - drm_connector_register(connector); } -- cgit v1.2.3 From 1dac891c1c95a8528f3558b481fbb9a45d653619 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:17 +0100 Subject: drm/i915: Register debugfs interface last MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently debugfs files are created before the driver is even loads. This gives the opportunity for userspace to open that interface and poke around before the backing data structures are initialised - with the possibility of oopsing or worse. Move the creation of the debugfs files to our registration phase, where we announce our presence to the world when we are ready, i.e the sequence changes from drm_dev_register() -> drm_minor_register() -> drm_debugfs_init() -> i915_debugfs_init() -> i915_driver_load() to drm_dev_register() -> drm_minor_register() -> drm_debugfs_init() -> i915_driver_load() -> i915_debugfs_register() Signed-off-by: Chris Wilson Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-5-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++-- drivers/gpu/drm/i915/i915_dma.c | 2 ++ drivers/gpu/drm/i915/i915_drv.c | 4 ---- drivers/gpu/drm/i915/i915_drv.h | 6 ++++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9989b6a26b17..a8e0eb7e146c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -5508,8 +5508,9 @@ void intel_display_crc_init(struct drm_device *dev) } } -int i915_debugfs_init(struct drm_minor *minor) +int i915_debugfs_register(struct drm_i915_private *dev_priv) { + struct drm_minor *minor = dev_priv->dev->primary; int ret, i; ret = i915_forcewake_create(minor->debugfs_root, minor); @@ -5535,8 +5536,9 @@ int i915_debugfs_init(struct drm_minor *minor) minor->debugfs_root, minor); } -void i915_debugfs_cleanup(struct drm_minor *minor) +void i915_debugfs_unregister(struct drm_i915_private *dev_priv) { + struct drm_minor *minor = dev_priv->dev->primary; int i; drm_debugfs_remove_files(i915_debugfs_list, diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 29521c4b87a5..91623874f9a3 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1397,6 +1397,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) if (intel_vgpu_active(dev_priv)) I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + i915_debugfs_register(dev_priv); i915_setup_sysfs(dev); intel_modeset_register(dev_priv); @@ -1433,6 +1434,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) intel_opregion_unregister(dev_priv); intel_modeset_unregister(dev_priv); i915_teardown_sysfs(dev_priv->dev); + i915_debugfs_unregister(dev_priv); i915_gem_shrinker_cleanup(dev_priv); } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3eb47fbcea73..3ea09bd83a5a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1756,10 +1756,6 @@ static struct drm_driver driver = { .postclose = i915_driver_postclose, .set_busid = drm_pci_set_busid, -#if defined(CONFIG_DEBUG_FS) - .debugfs_init = i915_debugfs_init, - .debugfs_cleanup = i915_debugfs_cleanup, -#endif .gem_free_object = i915_gem_free_object, .gem_vm_ops = &i915_gem_vm_ops, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 73683b54da7a..fe75f11d5e1b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3603,12 +3603,14 @@ int i915_verify_lists(struct drm_device *dev); #endif /* i915_debugfs.c */ -int i915_debugfs_init(struct drm_minor *minor); -void i915_debugfs_cleanup(struct drm_minor *minor); #ifdef CONFIG_DEBUG_FS +int i915_debugfs_register(struct drm_i915_private *dev_priv); +void i915_debugfs_unregister(struct drm_i915_private *dev_priv); int i915_debugfs_connector_add(struct drm_connector *connector); void intel_display_crc_init(struct drm_device *dev); #else +static inline int i915_debugfs_register(struct drm_i915_private *) {return 0;} +static inline void i915_debugfs_unregister(struct drm_i915_private *) {} static inline int i915_debugfs_connector_add(struct drm_connector *connector) { return 0; } static inline void intel_display_crc_init(struct drm_device *dev) {} -- cgit v1.2.3 From 8f460e2c78f211f71c274001facb36b03af2ebc6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:18 +0100 Subject: drm/i915: Demidlayer driver loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take control over allocating, loading and registering the driver from the DRM midlayer by performing it manually from i915_pci_probe. This allows us to carefully control the order of when we setup the hardware vs when it becomes visible to third parties (including userspace). The current ordering makes the driver visible to userspace first (in order to coordinate with removed DRI1 userspace), but that ordering incurs risk. The risk increases as we strive for more asynchronous loading. One side effect of controlling the allocation is that we can allocate both the drm_device + drm_i915_private in one block, the next step towards subclassing. Unload is still left as before, a mix of midlayer and driver. v2: After drm_dev_init(), we should call drm_dev_unref() so that we call drm_dev_release() and free everything from drm_dev_init(). v3: Fixup missed error code for failing to allocate dev_priv Suggested-by: Daniel Vetter Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-6-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_dma.c | 78 ++++++++++++++++++++++++++--------------- drivers/gpu/drm/i915/i915_drv.c | 3 +- drivers/gpu/drm/i915/i915_drv.h | 6 +++- 3 files changed, 55 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 91623874f9a3..5003962ec5b8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1075,9 +1075,10 @@ static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) * function hooks not requiring accessing the device. */ static int i915_driver_init_early(struct drm_i915_private *dev_priv, - struct drm_device *dev, - struct intel_device_info *info) + const struct pci_device_id *ent) { + const struct intel_device_info *match_info = + (struct intel_device_info *)ent->driver_data; struct intel_device_info *device_info; int ret = 0; @@ -1086,8 +1087,8 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, /* Setup the write-once "constant" device info */ device_info = (struct intel_device_info *)&dev_priv->info; - memcpy(device_info, info, sizeof(dev_priv->info)); - device_info->device_id = dev->pdev->device; + memcpy(device_info, match_info, sizeof(*device_info)); + device_info->device_id = dev_priv->drm.pdev->device; BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE); device_info->gen_mask = BIT(device_info->gen - 1); @@ -1113,18 +1114,18 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, goto err_workqueues; /* This must be called before any calls to HAS_PCH_* */ - intel_detect_pch(dev); + intel_detect_pch(&dev_priv->drm); - intel_pm_setup(dev); + intel_pm_setup(&dev_priv->drm); intel_init_dpio(dev_priv); intel_power_domains_init(dev_priv); intel_irq_init(dev_priv); intel_init_display_hooks(dev_priv); intel_init_clock_gating_hooks(dev_priv); intel_init_audio_hooks(dev_priv); - i915_gem_load_init(dev); + i915_gem_load_init(&dev_priv->drm); - intel_display_crc_init(dev); + intel_display_crc_init(&dev_priv->drm); i915_dump_device_info(dev_priv); @@ -1132,7 +1133,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, * very first ones. Almost everything should work, except for maybe * suspend/resume. And we don't implement workarounds that affect only * pre-production machines. */ - if (IS_HSW_EARLY_SDV(dev)) + if (IS_HSW_EARLY_SDV(dev_priv)) DRM_INFO("This is an early pre-production Haswell machine. " "It may not be fully functional.\n"); @@ -1390,6 +1391,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) struct drm_device *dev = dev_priv->dev; i915_gem_shrinker_init(dev_priv); + /* * Notify a valid surface after modesetting, * when running inside a VM. @@ -1397,9 +1399,13 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) if (intel_vgpu_active(dev_priv)) I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); - i915_debugfs_register(dev_priv); - i915_setup_sysfs(dev); - intel_modeset_register(dev_priv); + /* Reveal our presence to userspace */ + if (drm_dev_register(dev, 0) == 0) { + i915_debugfs_register(dev_priv); + i915_setup_sysfs(dev); + intel_modeset_register(dev_priv); + } else + DRM_ERROR("Failed to register driver for userspace access!\n"); if (INTEL_INFO(dev_priv)->num_pipes) { /* Must be done after probing outputs */ @@ -1449,24 +1455,38 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) * - allocate initial config memory * - setup the DRM framebuffer with the allocated memory */ -int i915_driver_load(struct drm_device *dev, unsigned long flags) +int i915_driver_load(struct pci_dev *pdev, + const struct pci_device_id *ent, + struct drm_driver *driver) { struct drm_i915_private *dev_priv; - int ret = 0; + int ret; + ret = -ENOMEM; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; + if (dev_priv) + ret = drm_dev_init(&dev_priv->drm, driver, &pdev->dev); + if (ret) { + dev_printk(KERN_ERR, &pdev->dev, + "[" DRM_NAME ":%s] allocation failed\n", __func__); + kfree(dev_priv); + return ret; + } - dev->dev_private = dev_priv; /* Must be set before calling __i915_printk */ - dev_priv->dev = dev; + dev_priv->drm.pdev = pdev; + dev_priv->drm.dev_private = dev_priv; + dev_priv->dev = &dev_priv->drm; - ret = i915_driver_init_early(dev_priv, dev, - (struct intel_device_info *)flags); + ret = pci_enable_device(pdev); + if (ret) + goto out_free_priv; + + pci_set_drvdata(pdev, &dev_priv->drm); + ret = i915_driver_init_early(dev_priv, ent); if (ret < 0) - goto out_free_priv; + goto out_pci_disable; intel_runtime_pm_get(dev_priv); @@ -1483,13 +1503,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) * of the i915_driver_init_/i915_driver_register functions according * to the role/effect of the given init step. */ - if (INTEL_INFO(dev)->num_pipes) { - ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); + if (INTEL_INFO(dev_priv)->num_pipes) { + ret = drm_vblank_init(dev_priv->dev, + INTEL_INFO(dev_priv)->num_pipes); if (ret) goto out_cleanup_hw; } - ret = i915_load_modeset_init(dev); + ret = i915_load_modeset_init(dev_priv->dev); if (ret < 0) goto out_cleanup_vblank; @@ -1502,7 +1523,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return 0; out_cleanup_vblank: - drm_vblank_cleanup(dev); + drm_vblank_cleanup(dev_priv->dev); out_cleanup_hw: i915_driver_cleanup_hw(dev_priv); out_cleanup_mmio: @@ -1510,11 +1531,11 @@ out_cleanup_mmio: out_runtime_pm_put: intel_runtime_pm_put(dev_priv); i915_driver_cleanup_early(dev_priv); +out_pci_disable: + pci_disable_device(pdev); out_free_priv: i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret); - - kfree(dev_priv); - + drm_dev_unref(&dev_priv->drm); return ret; } @@ -1579,7 +1600,6 @@ int i915_driver_unload(struct drm_device *dev) intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); i915_driver_cleanup_early(dev_priv); - kfree(dev_priv); return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3ea09bd83a5a..1a335e1a8b62 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1034,7 +1034,7 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (vga_switcheroo_client_probe_defer(pdev)) return -EPROBE_DEFER; - return drm_get_pci_dev(pdev, ent, &driver); + return i915_driver_load(pdev, ent, &driver); } static void @@ -1748,7 +1748,6 @@ static struct drm_driver driver = { .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET, - .load = i915_driver_load, .unload = i915_driver_unload, .open = i915_driver_open, .lastclose = i915_driver_lastclose, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fe75f11d5e1b..3e94edb1a9e1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1733,6 +1733,8 @@ struct intel_wm_config { }; struct drm_i915_private { + struct drm_device drm; + struct drm_device *dev; struct kmem_cache *objects; struct kmem_cache *vmas; @@ -2909,7 +2911,9 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level, #define i915_report_error(dev_priv, fmt, ...) \ __i915_printk(dev_priv, KERN_ERR, fmt, ##__VA_ARGS__) -extern int i915_driver_load(struct drm_device *, unsigned long flags); +extern int i915_driver_load(struct pci_dev *pdev, + const struct pci_device_id *ent, + struct drm_driver *driver); extern int i915_driver_unload(struct drm_device *); extern int i915_driver_open(struct drm_device *dev, struct drm_file *file); extern void i915_driver_lastclose(struct drm_device * dev); -- cgit v1.2.3 From 3e783bac8ade7dd66f97cb748582035356a210ba Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:19 +0100 Subject: drm/i915: Demidlayer driver unloading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To complete the transition to manual control of load/unload, we need to take over unloading from i915_pci_remove(). This allows us to correctly order our unregister vs shutdown phases, which currently are inverted due to the midlayer. However, the unload sequence is still invalid as we shutdown the driver with the last reference. Ideally, all we want to do is remove the userspace access on device removal, deferring the cleanup to the drm_dev_release() - breaking the reference cycles is then left as an exercise for the reader. Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Ville Syrjälä Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-7-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_dma.c | 4 ++++ drivers/gpu/drm/i915/i915_drv.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 5003962ec5b8..a9c2f635aaab 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1435,12 +1435,16 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) static void i915_driver_unregister(struct drm_i915_private *dev_priv) { i915_audio_component_cleanup(dev_priv); + intel_gpu_ips_teardown(); acpi_video_unregister(); intel_opregion_unregister(dev_priv); + intel_modeset_unregister(dev_priv); i915_teardown_sysfs(dev_priv->dev); i915_debugfs_unregister(dev_priv); + drm_dev_unregister(dev_priv->dev); + i915_gem_shrinker_cleanup(dev_priv); } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1a335e1a8b62..9ddae6add9e0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1042,7 +1042,8 @@ i915_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); - drm_put_dev(dev); + i915_driver_unload(dev); + drm_dev_unref(dev); } static int i915_pm_suspend(struct device *dev) @@ -1748,7 +1749,6 @@ static struct drm_driver driver = { .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET, - .unload = i915_driver_unload, .open = i915_driver_open, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, -- cgit v1.2.3 From 2e5673e73d01fa26ded3888629e5fe22b75ee0a5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:20 +0100 Subject: drm/i915: Remove redundant drm_connector_register_all() drm_connector_register_all() is now automatically called by drm_dev_register(), and so we no longer have to do so ourselves (via intel_modeset_register() after calling drm_dev_register()). Similarly for unregistering. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-8-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_dma.c | 2 -- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/intel_display.c | 10 ---------- 3 files changed, 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a9c2f635aaab..77c3e2373ad9 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1403,7 +1403,6 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) if (drm_dev_register(dev, 0) == 0) { i915_debugfs_register(dev_priv); i915_setup_sysfs(dev); - intel_modeset_register(dev_priv); } else DRM_ERROR("Failed to register driver for userspace access!\n"); @@ -1440,7 +1439,6 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) acpi_video_unregister(); intel_opregion_unregister(dev_priv); - intel_modeset_unregister(dev_priv); i915_teardown_sysfs(dev_priv->dev); i915_debugfs_unregister(dev_priv); drm_dev_unregister(dev_priv->dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3e94edb1a9e1..520ee8a6bb7a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3740,8 +3740,6 @@ extern void intel_modeset_init_hw(struct drm_device *dev); extern void intel_modeset_init(struct drm_device *dev); extern void intel_modeset_gem_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); -extern void intel_modeset_register(struct drm_i915_private *dev_priv); -extern void intel_modeset_unregister(struct drm_i915_private *dev_priv); extern int intel_connector_register(struct drm_connector *); extern void intel_connector_unregister(struct drm_connector *); extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 798c175c37bf..c3257177d527 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15551,16 +15551,6 @@ void intel_modeset_init_hw(struct drm_device *dev) intel_enable_gt_powersave(dev_priv); } -void intel_modeset_register(struct drm_i915_private *dev_priv) -{ - drm_connector_register_all(dev_priv->dev); -} - -void intel_modeset_unregister(struct drm_i915_private *dev_priv) -{ - drm_connector_unregister_all(dev_priv->dev); -} - /* * Calculate what we think the watermarks should be for the state we've read * out of the hardware and then immediately program those watermarks so that -- cgit v1.2.3 From 091387c1cb8b20ca0490bb35210ddb0c3d7d76ff Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:21 +0100 Subject: drm/i915: Start exploiting drm_device subclassing Baby step, update to_i915() conversion from drm_device to drm_i915_private: text data bss dec hex filename 1108812 23207 416 1132435 114793 i915.ko (before) 1104999 23207 416 1128622 1138ae i915.ko (after) Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Cc: Daniel Vetter Reviewed-by: Tvrtko Ursulin Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-9-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 520ee8a6bb7a..e0fc47b8b7ee 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2046,7 +2046,7 @@ struct drm_i915_private { static inline struct drm_i915_private *to_i915(const struct drm_device *dev) { - return dev->dev_private; + return container_of(dev, struct drm_i915_private, drm); } static inline struct drm_i915_private *dev_to_i915(struct device *dev) @@ -2622,7 +2622,7 @@ struct drm_i915_cmd_table { #define INTEL_DEVID(p) (INTEL_INFO(p)->device_id) #define REVID_FOREVER 0xff -#define INTEL_REVID(p) (__I915__(p)->dev->pdev->revision) +#define INTEL_REVID(p) (__I915__(p)->drm.pdev->revision) #define GEN_FOREVER (0) /* @@ -3501,7 +3501,7 @@ i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id) { struct i915_gem_context *ctx; - lockdep_assert_held(&file_priv->dev_priv->dev->struct_mutex); + lockdep_assert_held(&file_priv->dev_priv->drm.struct_mutex); ctx = idr_find(&file_priv->context_idr, id); if (!ctx) @@ -3517,7 +3517,7 @@ static inline void i915_gem_context_reference(struct i915_gem_context *ctx) static inline void i915_gem_context_unreference(struct i915_gem_context *ctx) { - lockdep_assert_held(&ctx->i915->dev->struct_mutex); + lockdep_assert_held(&ctx->i915->drm.struct_mutex); kref_put(&ctx->ref, i915_gem_context_free); } @@ -3593,7 +3593,7 @@ void i915_gem_shrinker_cleanup(struct drm_i915_private *dev_priv); /* i915_gem_tiling.c */ static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && obj->tiling_mode != I915_TILING_NONE; -- cgit v1.2.3 From 0673ad472b9849ad6dbd83d5e3a3a63aba5db740 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:22 +0100 Subject: drm/i915: Merge i915_dma.c into i915_drv.c i915_dma.c used to contain the DRI1/UMS horror show, but now all that remains are the out-of-place driver level interfaces (such as allocating, initialising and registering the driver). These should be in i915_drv.c alongside similar routines for suspend/resume. Signed-off-by: Chris Wilson Cc: Daniel Vetter Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-10-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/Makefile | 3 - drivers/gpu/drm/i915/i915_dma.c | 1715 -------------------------------- drivers/gpu/drm/i915/i915_drv.c | 2085 +++++++++++++++++++++++++++++++++++---- drivers/gpu/drm/i915/i915_drv.h | 16 +- 4 files changed, 1876 insertions(+), 1943 deletions(-) delete mode 100644 drivers/gpu/drm/i915/i915_dma.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 276abf1cac2b..c07cfb649f32 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -101,9 +101,6 @@ i915-y += dvo_ch7017.o \ # virtual gpu code i915-y += i915_vgpu.o -# legacy horrors -i915-y += i915_dma.o - ifeq ($(CONFIG_DRM_I915_GVT),y) i915-y += intel_gvt.o include $(src)/gvt/Makefile diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c deleted file mode 100644 index 77c3e2373ad9..000000000000 --- a/drivers/gpu/drm/i915/i915_dma.c +++ /dev/null @@ -1,1715 +0,0 @@ -/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- - */ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, 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. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include "intel_drv.h" -#include -#include "i915_drv.h" -#include "i915_vgpu.h" -#include "i915_trace.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned int i915_load_fail_count; - -bool __i915_inject_load_failure(const char *func, int line) -{ - if (i915_load_fail_count >= i915.inject_load_failure) - return false; - - if (++i915_load_fail_count == i915.inject_load_failure) { - DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n", - i915.inject_load_failure, func, line); - return true; - } - - return false; -} - -#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI" -#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \ - "providing the dmesg log by booting with drm.debug=0xf" - -void -__i915_printk(struct drm_i915_private *dev_priv, const char *level, - const char *fmt, ...) -{ - static bool shown_bug_once; - struct device *dev = dev_priv->dev->dev; - bool is_error = level[1] <= KERN_ERR[1]; - bool is_debug = level[1] == KERN_DEBUG[1]; - struct va_format vaf; - va_list args; - - if (is_debug && !(drm_debug & DRM_UT_DRIVER)) - return; - - va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV", - __builtin_return_address(0), &vaf); - - if (is_error && !shown_bug_once) { - dev_notice(dev, "%s", FDO_BUG_MSG); - shown_bug_once = true; - } - - va_end(args); -} - -static bool i915_error_injected(struct drm_i915_private *dev_priv) -{ - return i915.inject_load_failure && - i915_load_fail_count == i915.inject_load_failure; -} - -#define i915_load_error(dev_priv, fmt, ...) \ - __i915_printk(dev_priv, \ - i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \ - fmt, ##__VA_ARGS__) - -static int i915_getparam(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - drm_i915_getparam_t *param = data; - int value; - - switch (param->param) { - case I915_PARAM_IRQ_ACTIVE: - case I915_PARAM_ALLOW_BATCHBUFFER: - case I915_PARAM_LAST_DISPATCH: - /* Reject all old ums/dri params. */ - return -ENODEV; - case I915_PARAM_CHIPSET_ID: - value = dev->pdev->device; - break; - case I915_PARAM_REVISION: - value = dev->pdev->revision; - break; - case I915_PARAM_HAS_GEM: - value = 1; - break; - case I915_PARAM_NUM_FENCES_AVAIL: - value = dev_priv->num_fence_regs; - break; - case I915_PARAM_HAS_OVERLAY: - value = dev_priv->overlay ? 1 : 0; - break; - case I915_PARAM_HAS_PAGEFLIPPING: - value = 1; - break; - case I915_PARAM_HAS_EXECBUF2: - /* depends on GEM */ - value = 1; - break; - case I915_PARAM_HAS_BSD: - value = intel_engine_initialized(&dev_priv->engine[VCS]); - break; - case I915_PARAM_HAS_BLT: - value = intel_engine_initialized(&dev_priv->engine[BCS]); - break; - case I915_PARAM_HAS_VEBOX: - value = intel_engine_initialized(&dev_priv->engine[VECS]); - break; - case I915_PARAM_HAS_BSD2: - value = intel_engine_initialized(&dev_priv->engine[VCS2]); - break; - case I915_PARAM_HAS_RELAXED_FENCING: - value = 1; - break; - case I915_PARAM_HAS_COHERENT_RINGS: - value = 1; - break; - case I915_PARAM_HAS_EXEC_CONSTANTS: - value = INTEL_INFO(dev)->gen >= 4; - break; - case I915_PARAM_HAS_RELAXED_DELTA: - value = 1; - break; - case I915_PARAM_HAS_GEN7_SOL_RESET: - value = 1; - break; - case I915_PARAM_HAS_LLC: - value = HAS_LLC(dev); - break; - case I915_PARAM_HAS_WT: - value = HAS_WT(dev); - break; - case I915_PARAM_HAS_ALIASING_PPGTT: - value = USES_PPGTT(dev); - break; - case I915_PARAM_HAS_WAIT_TIMEOUT: - value = 1; - break; - case I915_PARAM_HAS_SEMAPHORES: - value = i915_semaphore_is_enabled(dev_priv); - break; - case I915_PARAM_HAS_PRIME_VMAP_FLUSH: - value = 1; - break; - case I915_PARAM_HAS_SECURE_BATCHES: - value = capable(CAP_SYS_ADMIN); - break; - case I915_PARAM_HAS_PINNED_BATCHES: - value = 1; - break; - case I915_PARAM_HAS_EXEC_NO_RELOC: - value = 1; - break; - case I915_PARAM_HAS_EXEC_HANDLE_LUT: - value = 1; - break; - case I915_PARAM_CMD_PARSER_VERSION: - value = i915_cmd_parser_get_version(dev_priv); - break; - case I915_PARAM_HAS_COHERENT_PHYS_GTT: - value = 1; - break; - case I915_PARAM_MMAP_VERSION: - value = 1; - break; - case I915_PARAM_SUBSLICE_TOTAL: - value = INTEL_INFO(dev)->subslice_total; - if (!value) - return -ENODEV; - break; - case I915_PARAM_EU_TOTAL: - value = INTEL_INFO(dev)->eu_total; - if (!value) - return -ENODEV; - break; - case I915_PARAM_HAS_GPU_RESET: - value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv); - break; - case I915_PARAM_HAS_RESOURCE_STREAMER: - value = HAS_RESOURCE_STREAMER(dev); - break; - case I915_PARAM_HAS_EXEC_SOFTPIN: - value = 1; - break; - default: - DRM_DEBUG("Unknown parameter %d\n", param->param); - return -EINVAL; - } - - if (copy_to_user(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user failed\n"); - return -EFAULT; - } - - return 0; -} - -static int i915_get_bridge_dev(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); - if (!dev_priv->bridge_dev) { - DRM_ERROR("bridge device not found\n"); - return -1; - } - return 0; -} - -/* Allocate space for the MCH regs if needed, return nonzero on error */ -static int -intel_alloc_mchbar_resource(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; - u32 temp_lo, temp_hi = 0; - u64 mchbar_addr; - int ret; - - if (INTEL_INFO(dev)->gen >= 4) - pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); - pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); - mchbar_addr = ((u64)temp_hi << 32) | temp_lo; - - /* If ACPI doesn't have it, assume we need to allocate it ourselves */ -#ifdef CONFIG_PNP - if (mchbar_addr && - pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) - return 0; -#endif - - /* Get some space for it */ - dev_priv->mch_res.name = "i915 MCHBAR"; - dev_priv->mch_res.flags = IORESOURCE_MEM; - ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, - &dev_priv->mch_res, - MCHBAR_SIZE, MCHBAR_SIZE, - PCIBIOS_MIN_MEM, - 0, pcibios_align_resource, - dev_priv->bridge_dev); - if (ret) { - DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); - dev_priv->mch_res.start = 0; - return ret; - } - - if (INTEL_INFO(dev)->gen >= 4) - pci_write_config_dword(dev_priv->bridge_dev, reg + 4, - upper_32_bits(dev_priv->mch_res.start)); - - pci_write_config_dword(dev_priv->bridge_dev, reg, - lower_32_bits(dev_priv->mch_res.start)); - return 0; -} - -/* Setup MCHBAR if possible, return true if we should disable it again */ -static void -intel_setup_mchbar(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; - u32 temp; - bool enabled; - - if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) - return; - - dev_priv->mchbar_need_disable = false; - - if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_read_config_dword(dev_priv->bridge_dev, DEVEN, &temp); - enabled = !!(temp & DEVEN_MCHBAR_EN); - } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - enabled = temp & 1; - } - - /* If it's already enabled, don't have to do anything */ - if (enabled) - return; - - if (intel_alloc_mchbar_resource(dev)) - return; - - dev_priv->mchbar_need_disable = true; - - /* Space is allocated or reserved, so enable it. */ - if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_write_config_dword(dev_priv->bridge_dev, DEVEN, - temp | DEVEN_MCHBAR_EN); - } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1); - } -} - -static void -intel_teardown_mchbar(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; - - if (dev_priv->mchbar_need_disable) { - if (IS_I915G(dev) || IS_I915GM(dev)) { - u32 deven_val; - - pci_read_config_dword(dev_priv->bridge_dev, DEVEN, - &deven_val); - deven_val &= ~DEVEN_MCHBAR_EN; - pci_write_config_dword(dev_priv->bridge_dev, DEVEN, - deven_val); - } else { - u32 mchbar_val; - - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, - &mchbar_val); - mchbar_val &= ~1; - pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, - mchbar_val); - } - } - - if (dev_priv->mch_res.start) - release_resource(&dev_priv->mch_res); -} - -/* true = enable decode, false = disable decoder */ -static unsigned int i915_vga_set_decode(void *cookie, bool state) -{ - struct drm_device *dev = cookie; - - intel_modeset_vga_set_state(dev, state); - if (state) - return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | - VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; - else - return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; -} - -static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; - - if (state == VGA_SWITCHEROO_ON) { - pr_info("switched on\n"); - dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - /* i915 resume handler doesn't set to D0 */ - pci_set_power_state(dev->pdev, PCI_D0); - i915_resume_switcheroo(dev); - dev->switch_power_state = DRM_SWITCH_POWER_ON; - } else { - pr_info("switched off\n"); - dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; - i915_suspend_switcheroo(dev, pmm); - dev->switch_power_state = DRM_SWITCH_POWER_OFF; - } -} - -static bool i915_switcheroo_can_switch(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - /* - * FIXME: open_count is protected by drm_global_mutex but that would lead to - * locking inversion with the driver load path. And the access here is - * completely racy anyway. So don't bother with locking for now. - */ - return dev->open_count == 0; -} - -static const struct vga_switcheroo_client_ops i915_switcheroo_ops = { - .set_gpu_state = i915_switcheroo_set_state, - .reprobe = NULL, - .can_switch = i915_switcheroo_can_switch, -}; - -static void i915_gem_fini(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - /* - * Neither the BIOS, ourselves or any other kernel - * expects the system to be in execlists mode on startup, - * so we need to reset the GPU back to legacy mode. And the only - * known way to disable logical contexts is through a GPU reset. - * - * So in order to leave the system in a known default configuration, - * always reset the GPU upon unload. Afterwards we then clean up the - * GEM state tracking, flushing off the requests and leaving the - * system in a known idle state. - * - * Note that is of the upmost importance that the GPU is idle and - * all stray writes are flushed *before* we dismantle the backing - * storage for the pinned objects. - * - * However, since we are uncertain that reseting the GPU on older - * machines is a good idea, we don't - just in case it leaves the - * machine in an unusable condition. - */ - if (HAS_HW_CONTEXTS(dev)) { - int reset = intel_gpu_reset(dev_priv, ALL_ENGINES); - WARN_ON(reset && reset != -ENODEV); - } - - mutex_lock(&dev->struct_mutex); - i915_gem_reset(dev); - i915_gem_cleanup_engines(dev); - i915_gem_context_fini(dev); - mutex_unlock(&dev->struct_mutex); - - WARN_ON(!list_empty(&to_i915(dev)->context_list)); -} - -static int i915_load_modeset_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - if (i915_inject_load_failure()) - return -ENODEV; - - ret = intel_bios_init(dev_priv); - if (ret) - DRM_INFO("failed to find VBIOS tables\n"); - - /* If we have > 1 VGA cards, then we need to arbitrate access - * to the common VGA resources. - * - * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), - * then we do not take part in VGA arbitration and the - * vga_client_register() fails with -ENODEV. - */ - ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); - if (ret && ret != -ENODEV) - goto out; - - intel_register_dsm_handler(); - - ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false); - if (ret) - goto cleanup_vga_client; - - /* must happen before intel_power_domains_init_hw() on VLV/CHV */ - intel_update_rawclk(dev_priv); - - intel_power_domains_init_hw(dev_priv, false); - - intel_csr_ucode_init(dev_priv); - - ret = intel_irq_install(dev_priv); - if (ret) - goto cleanup_csr; - - intel_setup_gmbus(dev); - - /* Important: The output setup functions called by modeset_init need - * working irqs for e.g. gmbus and dp aux transfers. */ - intel_modeset_init(dev); - - intel_guc_init(dev); - - ret = i915_gem_init(dev); - if (ret) - goto cleanup_irq; - - intel_modeset_gem_init(dev); - - if (INTEL_INFO(dev)->num_pipes == 0) - return 0; - - ret = intel_fbdev_init(dev); - if (ret) - goto cleanup_gem; - - /* Only enable hotplug handling once the fbdev is fully set up. */ - intel_hpd_init(dev_priv); - - drm_kms_helper_poll_init(dev); - - return 0; - -cleanup_gem: - i915_gem_fini(dev); -cleanup_irq: - intel_guc_fini(dev); - drm_irq_uninstall(dev); - intel_teardown_gmbus(dev); -cleanup_csr: - intel_csr_ucode_fini(dev_priv); - intel_power_domains_fini(dev_priv); - vga_switcheroo_unregister_client(dev->pdev); -cleanup_vga_client: - vga_client_register(dev->pdev, NULL, NULL, NULL); -out: - return ret; -} - -#if IS_ENABLED(CONFIG_FB) -static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) -{ - struct apertures_struct *ap; - struct pci_dev *pdev = dev_priv->dev->pdev; - struct i915_ggtt *ggtt = &dev_priv->ggtt; - bool primary; - int ret; - - ap = alloc_apertures(1); - if (!ap) - return -ENOMEM; - - ap->ranges[0].base = ggtt->mappable_base; - ap->ranges[0].size = ggtt->mappable_end; - - primary = - pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; - - ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary); - - kfree(ap); - - return ret; -} -#else -static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) -{ - return 0; -} -#endif - -#if !defined(CONFIG_VGA_CONSOLE) -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) -{ - return 0; -} -#elif !defined(CONFIG_DUMMY_CONSOLE) -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) -{ - return -ENODEV; -} -#else -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) -{ - int ret = 0; - - DRM_INFO("Replacing VGA console driver\n"); - - console_lock(); - if (con_is_bound(&vga_con)) - ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1); - if (ret == 0) { - ret = do_unregister_con_driver(&vga_con); - - /* Ignore "already unregistered". */ - if (ret == -ENODEV) - ret = 0; - } - console_unlock(); - - return ret; -} -#endif - -static void i915_dump_device_info(struct drm_i915_private *dev_priv) -{ - const struct intel_device_info *info = &dev_priv->info; - -#define PRINT_S(name) "%s" -#define SEP_EMPTY -#define PRINT_FLAG(name) info->name ? #name "," : "" -#define SEP_COMMA , - DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x rev=0x%02x flags=" - DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY), - info->gen, - dev_priv->dev->pdev->device, - dev_priv->dev->pdev->revision, - DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA)); -#undef PRINT_S -#undef SEP_EMPTY -#undef PRINT_FLAG -#undef SEP_COMMA -} - -static void cherryview_sseu_info_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_device_info *info; - u32 fuse, eu_dis; - - info = (struct intel_device_info *)&dev_priv->info; - fuse = I915_READ(CHV_FUSE_GT); - - info->slice_total = 1; - - if (!(fuse & CHV_FGT_DISABLE_SS0)) { - info->subslice_per_slice++; - eu_dis = fuse & (CHV_FGT_EU_DIS_SS0_R0_MASK | - CHV_FGT_EU_DIS_SS0_R1_MASK); - info->eu_total += 8 - hweight32(eu_dis); - } - - if (!(fuse & CHV_FGT_DISABLE_SS1)) { - info->subslice_per_slice++; - eu_dis = fuse & (CHV_FGT_EU_DIS_SS1_R0_MASK | - CHV_FGT_EU_DIS_SS1_R1_MASK); - info->eu_total += 8 - hweight32(eu_dis); - } - - info->subslice_total = info->subslice_per_slice; - /* - * CHV expected to always have a uniform distribution of EU - * across subslices. - */ - info->eu_per_subslice = info->subslice_total ? - info->eu_total / info->subslice_total : - 0; - /* - * CHV supports subslice power gating on devices with more than - * one subslice, and supports EU power gating on devices with - * more than one EU pair per subslice. - */ - info->has_slice_pg = 0; - info->has_subslice_pg = (info->subslice_total > 1); - info->has_eu_pg = (info->eu_per_subslice > 2); -} - -static void gen9_sseu_info_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_device_info *info; - int s_max = 3, ss_max = 4, eu_max = 8; - int s, ss; - u32 fuse2, s_enable, ss_disable, eu_disable; - u8 eu_mask = 0xff; - - info = (struct intel_device_info *)&dev_priv->info; - fuse2 = I915_READ(GEN8_FUSE2); - s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> - GEN8_F2_S_ENA_SHIFT; - ss_disable = (fuse2 & GEN9_F2_SS_DIS_MASK) >> - GEN9_F2_SS_DIS_SHIFT; - - info->slice_total = hweight32(s_enable); - /* - * The subslice disable field is global, i.e. it applies - * to each of the enabled slices. - */ - info->subslice_per_slice = ss_max - hweight32(ss_disable); - info->subslice_total = info->slice_total * - info->subslice_per_slice; - - /* - * Iterate through enabled slices and subslices to - * count the total enabled EU. - */ - for (s = 0; s < s_max; s++) { - if (!(s_enable & (0x1 << s))) - /* skip disabled slice */ - continue; - - eu_disable = I915_READ(GEN9_EU_DISABLE(s)); - for (ss = 0; ss < ss_max; ss++) { - int eu_per_ss; - - if (ss_disable & (0x1 << ss)) - /* skip disabled subslice */ - continue; - - eu_per_ss = eu_max - hweight8((eu_disable >> (ss*8)) & - eu_mask); - - /* - * Record which subslice(s) has(have) 7 EUs. we - * can tune the hash used to spread work among - * subslices if they are unbalanced. - */ - if (eu_per_ss == 7) - info->subslice_7eu[s] |= 1 << ss; - - info->eu_total += eu_per_ss; - } - } - - /* - * SKL is expected to always have a uniform distribution - * of EU across subslices with the exception that any one - * EU in any one subslice may be fused off for die - * recovery. BXT is expected to be perfectly uniform in EU - * distribution. - */ - info->eu_per_subslice = info->subslice_total ? - DIV_ROUND_UP(info->eu_total, - info->subslice_total) : 0; - /* - * SKL supports slice power gating on devices with more than - * one slice, and supports EU power gating on devices with - * more than one EU pair per subslice. BXT supports subslice - * power gating on devices with more than one subslice, and - * supports EU power gating on devices with more than one EU - * pair per subslice. - */ - info->has_slice_pg = ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && - (info->slice_total > 1)); - info->has_subslice_pg = (IS_BROXTON(dev) && (info->subslice_total > 1)); - info->has_eu_pg = (info->eu_per_subslice > 2); - - if (IS_BROXTON(dev)) { -#define IS_SS_DISABLED(_ss_disable, ss) (_ss_disable & (0x1 << ss)) - /* - * There is a HW issue in 2x6 fused down parts that requires - * Pooled EU to be enabled as a WA. The pool configuration - * changes depending upon which subslice is fused down. This - * doesn't affect if the device has all 3 subslices enabled. - */ - /* WaEnablePooledEuFor2x6:bxt */ - info->has_pooled_eu = ((info->subslice_per_slice == 3) || - (info->subslice_per_slice == 2 && - INTEL_REVID(dev) < BXT_REVID_C0)); - - info->min_eu_in_pool = 0; - if (info->has_pooled_eu) { - if (IS_SS_DISABLED(ss_disable, 0) || - IS_SS_DISABLED(ss_disable, 2)) - info->min_eu_in_pool = 3; - else if (IS_SS_DISABLED(ss_disable, 1)) - info->min_eu_in_pool = 6; - else - info->min_eu_in_pool = 9; - } -#undef IS_SS_DISABLED - } -} - -static void broadwell_sseu_info_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_device_info *info; - const int s_max = 3, ss_max = 3, eu_max = 8; - int s, ss; - u32 fuse2, eu_disable[s_max], s_enable, ss_disable; - - fuse2 = I915_READ(GEN8_FUSE2); - s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT; - ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT; - - eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK; - eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) | - ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) << - (32 - GEN8_EU_DIS0_S1_SHIFT)); - eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) | - ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) << - (32 - GEN8_EU_DIS1_S2_SHIFT)); - - - info = (struct intel_device_info *)&dev_priv->info; - info->slice_total = hweight32(s_enable); - - /* - * The subslice disable field is global, i.e. it applies - * to each of the enabled slices. - */ - info->subslice_per_slice = ss_max - hweight32(ss_disable); - info->subslice_total = info->slice_total * info->subslice_per_slice; - - /* - * Iterate through enabled slices and subslices to - * count the total enabled EU. - */ - for (s = 0; s < s_max; s++) { - if (!(s_enable & (0x1 << s))) - /* skip disabled slice */ - continue; - - for (ss = 0; ss < ss_max; ss++) { - u32 n_disabled; - - if (ss_disable & (0x1 << ss)) - /* skip disabled subslice */ - continue; - - n_disabled = hweight8(eu_disable[s] >> (ss * eu_max)); - - /* - * Record which subslices have 7 EUs. - */ - if (eu_max - n_disabled == 7) - info->subslice_7eu[s] |= 1 << ss; - - info->eu_total += eu_max - n_disabled; - } - } - - /* - * BDW is expected to always have a uniform distribution of EU across - * subslices with the exception that any one EU in any one subslice may - * be fused off for die recovery. - */ - info->eu_per_subslice = info->subslice_total ? - DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0; - - /* - * BDW supports slice power gating on devices with more than - * one slice. - */ - info->has_slice_pg = (info->slice_total > 1); - info->has_subslice_pg = 0; - info->has_eu_pg = 0; -} - -/* - * Determine various intel_device_info fields at runtime. - * - * Use it when either: - * - it's judged too laborious to fill n static structures with the limit - * when a simple if statement does the job, - * - run-time checks (eg read fuse/strap registers) are needed. - * - * This function needs to be called: - * - after the MMIO has been setup as we are reading registers, - * - after the PCH has been detected, - * - before the first usage of the fields it can tweak. - */ -static void intel_device_info_runtime_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_device_info *info; - enum pipe pipe; - - info = (struct intel_device_info *)&dev_priv->info; - - /* - * Skylake and Broxton currently don't expose the topmost plane as its - * use is exclusive with the legacy cursor and we only want to expose - * one of those, not both. Until we can safely expose the topmost plane - * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported, - * we don't expose the topmost plane at all to prevent ABI breakage - * down the line. - */ - if (IS_BROXTON(dev)) { - info->num_sprites[PIPE_A] = 2; - info->num_sprites[PIPE_B] = 2; - info->num_sprites[PIPE_C] = 1; - } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) - for_each_pipe(dev_priv, pipe) - info->num_sprites[pipe] = 2; - else - for_each_pipe(dev_priv, pipe) - info->num_sprites[pipe] = 1; - - if (i915.disable_display) { - DRM_INFO("Display disabled (module parameter)\n"); - info->num_pipes = 0; - } else if (info->num_pipes > 0 && - (IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) && - HAS_PCH_SPLIT(dev)) { - u32 fuse_strap = I915_READ(FUSE_STRAP); - u32 sfuse_strap = I915_READ(SFUSE_STRAP); - - /* - * SFUSE_STRAP is supposed to have a bit signalling the display - * is fused off. Unfortunately it seems that, at least in - * certain cases, fused off display means that PCH display - * reads don't land anywhere. In that case, we read 0s. - * - * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK - * should be set when taking over after the firmware. - */ - if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE || - sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED || - (dev_priv->pch_type == PCH_CPT && - !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { - DRM_INFO("Display fused off, disabling\n"); - info->num_pipes = 0; - } else if (fuse_strap & IVB_PIPE_C_DISABLE) { - DRM_INFO("PipeC fused off\n"); - info->num_pipes -= 1; - } - } else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) { - u32 dfsm = I915_READ(SKL_DFSM); - u8 disabled_mask = 0; - bool invalid; - int num_bits; - - if (dfsm & SKL_DFSM_PIPE_A_DISABLE) - disabled_mask |= BIT(PIPE_A); - if (dfsm & SKL_DFSM_PIPE_B_DISABLE) - disabled_mask |= BIT(PIPE_B); - if (dfsm & SKL_DFSM_PIPE_C_DISABLE) - disabled_mask |= BIT(PIPE_C); - - num_bits = hweight8(disabled_mask); - - switch (disabled_mask) { - case BIT(PIPE_A): - case BIT(PIPE_B): - case BIT(PIPE_A) | BIT(PIPE_B): - case BIT(PIPE_A) | BIT(PIPE_C): - invalid = true; - break; - default: - invalid = false; - } - - if (num_bits > info->num_pipes || invalid) - DRM_ERROR("invalid pipe fuse configuration: 0x%x\n", - disabled_mask); - else - info->num_pipes -= num_bits; - } - - /* Initialize slice/subslice/EU info */ - if (IS_CHERRYVIEW(dev)) - cherryview_sseu_info_init(dev); - else if (IS_BROADWELL(dev)) - broadwell_sseu_info_init(dev); - else if (INTEL_INFO(dev)->gen >= 9) - gen9_sseu_info_init(dev); - - info->has_snoop = !info->has_llc; - - /* Snooping is broken on BXT A stepping. */ - if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) - info->has_snoop = false; - - DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total); - DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total); - DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice); - DRM_DEBUG_DRIVER("EU total: %u\n", info->eu_total); - DRM_DEBUG_DRIVER("EU per subslice: %u\n", info->eu_per_subslice); - DRM_DEBUG_DRIVER("Has Pooled EU: %s\n", HAS_POOLED_EU(dev) ? "y" : "n"); - if (HAS_POOLED_EU(dev)) - DRM_DEBUG_DRIVER("Min EU in pool: %u\n", info->min_eu_in_pool); - DRM_DEBUG_DRIVER("has slice power gating: %s\n", - info->has_slice_pg ? "y" : "n"); - DRM_DEBUG_DRIVER("has subslice power gating: %s\n", - info->has_subslice_pg ? "y" : "n"); - DRM_DEBUG_DRIVER("has EU power gating: %s\n", - info->has_eu_pg ? "y" : "n"); - - i915.enable_execlists = - intel_sanitize_enable_execlists(dev_priv, - i915.enable_execlists); - - /* - * i915.enable_ppgtt is read-only, so do an early pass to validate the - * user's requested state against the hardware/driver capabilities. We - * do this now so that we can print out any log messages once rather - * than every time we check intel_enable_ppgtt(). - */ - i915.enable_ppgtt = - intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt); - DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt); -} - -static void intel_init_dpio(struct drm_i915_private *dev_priv) -{ - /* - * IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C), - * CHV x1 PHY (DP/HDMI D) - * IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C) - */ - if (IS_CHERRYVIEW(dev_priv)) { - DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2; - DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO; - } else if (IS_VALLEYVIEW(dev_priv)) { - DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO; - } -} - -static int i915_workqueues_init(struct drm_i915_private *dev_priv) -{ - /* - * The i915 workqueue is primarily used for batched retirement of - * requests (and thus managing bo) once the task has been completed - * by the GPU. i915_gem_retire_requests() is called directly when we - * need high-priority retirement, such as waiting for an explicit - * bo. - * - * It is also used for periodic low-priority events, such as - * idle-timers and recording error state. - * - * All tasks on the workqueue are expected to acquire the dev mutex - * so there is no point in running more than one instance of the - * workqueue at any time. Use an ordered one. - */ - dev_priv->wq = alloc_ordered_workqueue("i915", 0); - if (dev_priv->wq == NULL) - goto out_err; - - dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0); - if (dev_priv->hotplug.dp_wq == NULL) - goto out_free_wq; - - dev_priv->gpu_error.hangcheck_wq = - alloc_ordered_workqueue("i915-hangcheck", 0); - if (dev_priv->gpu_error.hangcheck_wq == NULL) - goto out_free_dp_wq; - - return 0; - -out_free_dp_wq: - destroy_workqueue(dev_priv->hotplug.dp_wq); -out_free_wq: - destroy_workqueue(dev_priv->wq); -out_err: - DRM_ERROR("Failed to allocate workqueues.\n"); - - return -ENOMEM; -} - -static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) -{ - destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); - destroy_workqueue(dev_priv->hotplug.dp_wq); - destroy_workqueue(dev_priv->wq); -} - -/** - * i915_driver_init_early - setup state not requiring device access - * @dev_priv: device private - * - * Initialize everything that is a "SW-only" state, that is state not - * requiring accessing the device or exposing the driver via kernel internal - * or userspace interfaces. Example steps belonging here: lock initialization, - * system memory allocation, setting up device specific attributes and - * function hooks not requiring accessing the device. - */ -static int i915_driver_init_early(struct drm_i915_private *dev_priv, - const struct pci_device_id *ent) -{ - const struct intel_device_info *match_info = - (struct intel_device_info *)ent->driver_data; - struct intel_device_info *device_info; - int ret = 0; - - if (i915_inject_load_failure()) - return -ENODEV; - - /* Setup the write-once "constant" device info */ - device_info = (struct intel_device_info *)&dev_priv->info; - memcpy(device_info, match_info, sizeof(*device_info)); - device_info->device_id = dev_priv->drm.pdev->device; - - 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); - spin_lock_init(&dev_priv->uncore.lock); - spin_lock_init(&dev_priv->mm.object_stat_lock); - spin_lock_init(&dev_priv->mmio_flip_lock); - mutex_init(&dev_priv->sb_lock); - mutex_init(&dev_priv->modeset_restore_lock); - mutex_init(&dev_priv->av_mutex); - mutex_init(&dev_priv->wm.wm_mutex); - mutex_init(&dev_priv->pps_mutex); - - ret = i915_workqueues_init(dev_priv); - if (ret < 0) - return ret; - - ret = intel_gvt_init(dev_priv); - if (ret < 0) - goto err_workqueues; - - /* This must be called before any calls to HAS_PCH_* */ - intel_detect_pch(&dev_priv->drm); - - intel_pm_setup(&dev_priv->drm); - intel_init_dpio(dev_priv); - intel_power_domains_init(dev_priv); - intel_irq_init(dev_priv); - intel_init_display_hooks(dev_priv); - intel_init_clock_gating_hooks(dev_priv); - intel_init_audio_hooks(dev_priv); - i915_gem_load_init(&dev_priv->drm); - - intel_display_crc_init(&dev_priv->drm); - - i915_dump_device_info(dev_priv); - - /* Not all pre-production machines fall into this category, only the - * very first ones. Almost everything should work, except for maybe - * suspend/resume. And we don't implement workarounds that affect only - * pre-production machines. */ - if (IS_HSW_EARLY_SDV(dev_priv)) - DRM_INFO("This is an early pre-production Haswell machine. " - "It may not be fully functional.\n"); - - return 0; - -err_workqueues: - i915_workqueues_cleanup(dev_priv); - return ret; -} - -/** - * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early() - * @dev_priv: device private - */ -static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) -{ - i915_gem_load_cleanup(dev_priv->dev); - i915_workqueues_cleanup(dev_priv); -} - -static int i915_mmio_setup(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - int mmio_bar; - int mmio_size; - - mmio_bar = IS_GEN2(dev) ? 1 : 0; - /* - * Before gen4, the registers and the GTT are behind different BARs. - * However, from gen4 onwards, the registers and the GTT are shared - * in the same BAR, so we want to restrict this ioremap from - * clobbering the GTT which we want ioremap_wc instead. Fortunately, - * the register BAR remains the same size for all the earlier - * generations up to Ironlake. - */ - if (INTEL_INFO(dev)->gen < 5) - mmio_size = 512 * 1024; - else - mmio_size = 2 * 1024 * 1024; - dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size); - if (dev_priv->regs == NULL) { - DRM_ERROR("failed to map registers\n"); - - return -EIO; - } - - /* Try to make sure MCHBAR is enabled before poking at it */ - intel_setup_mchbar(dev); - - return 0; -} - -static void i915_mmio_cleanup(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = to_i915(dev); - - intel_teardown_mchbar(dev); - pci_iounmap(dev->pdev, dev_priv->regs); -} - -/** - * i915_driver_init_mmio - setup device MMIO - * @dev_priv: device private - * - * Setup minimal device state necessary for MMIO accesses later in the - * initialization sequence. The setup here should avoid any other device-wide - * side effects or exposing the driver via kernel internal or user space - * interfaces. - */ -static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - int ret; - - if (i915_inject_load_failure()) - return -ENODEV; - - if (i915_get_bridge_dev(dev)) - return -EIO; - - ret = i915_mmio_setup(dev); - if (ret < 0) - goto put_bridge; - - intel_uncore_init(dev_priv); - - return 0; - -put_bridge: - pci_dev_put(dev_priv->bridge_dev); - - return ret; -} - -/** - * i915_driver_cleanup_mmio - cleanup the setup done in i915_driver_init_mmio() - * @dev_priv: device private - */ -static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - - intel_uncore_fini(dev_priv); - i915_mmio_cleanup(dev); - pci_dev_put(dev_priv->bridge_dev); -} - -/** - * i915_driver_init_hw - setup state requiring device access - * @dev_priv: device private - * - * Setup state that requires accessing the device, but doesn't require - * exposing the driver via kernel internal or userspace interfaces. - */ -static int i915_driver_init_hw(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct i915_ggtt *ggtt = &dev_priv->ggtt; - uint32_t aperture_size; - int ret; - - if (i915_inject_load_failure()) - return -ENODEV; - - intel_device_info_runtime_init(dev); - - ret = i915_ggtt_init_hw(dev); - if (ret) - return ret; - - ret = i915_ggtt_enable_hw(dev); - if (ret) { - DRM_ERROR("failed to enable GGTT\n"); - goto out_ggtt; - } - - /* WARNING: Apparently we must kick fbdev drivers before vgacon, - * otherwise the vga fbdev driver falls over. */ - ret = i915_kick_out_firmware_fb(dev_priv); - if (ret) { - DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); - goto out_ggtt; - } - - ret = i915_kick_out_vgacon(dev_priv); - if (ret) { - DRM_ERROR("failed to remove conflicting VGA console\n"); - goto out_ggtt; - } - - pci_set_master(dev->pdev); - - /* overlay on gen2 is broken and can't address above 1G */ - if (IS_GEN2(dev)) { - ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); - if (ret) { - DRM_ERROR("failed to set DMA mask\n"); - - goto out_ggtt; - } - } - - - /* 965GM sometimes incorrectly writes to hardware status page (HWS) - * using 32bit addressing, overwriting memory if HWS is located - * above 4GB. - * - * The documentation also mentions an issue with undefined - * behaviour if any general state is accessed within a page above 4GB, - * which also needs to be handled carefully. - */ - if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) { - ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); - - if (ret) { - DRM_ERROR("failed to set DMA mask\n"); - - goto out_ggtt; - } - } - - aperture_size = ggtt->mappable_end; - - ggtt->mappable = - io_mapping_create_wc(ggtt->mappable_base, - aperture_size); - if (!ggtt->mappable) { - ret = -EIO; - goto out_ggtt; - } - - ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base, - aperture_size); - - pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - - intel_uncore_sanitize(dev_priv); - - intel_opregion_setup(dev_priv); - - i915_gem_load_init_fences(dev_priv); - - /* On the 945G/GM, the chipset reports the MSI capability on the - * integrated graphics even though the support isn't actually there - * according to the published specs. It doesn't appear to function - * correctly in testing on 945G. - * This may be a side effect of MSI having been made available for PEG - * and the registers being closely associated. - * - * According to chipset errata, on the 965GM, MSI interrupts may - * be lost or delayed, but we use them anyways to avoid - * stuck interrupts on some machines. - */ - if (!IS_I945G(dev) && !IS_I945GM(dev)) { - if (pci_enable_msi(dev->pdev) < 0) - DRM_DEBUG_DRIVER("can't enable MSI"); - } - - return 0; - -out_ggtt: - i915_ggtt_cleanup_hw(dev); - - return ret; -} - -/** - * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw() - * @dev_priv: device private - */ -static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - struct i915_ggtt *ggtt = &dev_priv->ggtt; - - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - - pm_qos_remove_request(&dev_priv->pm_qos); - arch_phys_wc_del(ggtt->mtrr); - io_mapping_free(ggtt->mappable); - i915_ggtt_cleanup_hw(dev); -} - -/** - * i915_driver_register - register the driver with the rest of the system - * @dev_priv: device private - * - * Perform any steps necessary to make the driver available via kernel - * internal or userspace interfaces. - */ -static void i915_driver_register(struct drm_i915_private *dev_priv) -{ - struct drm_device *dev = dev_priv->dev; - - i915_gem_shrinker_init(dev_priv); - - /* - * Notify a valid surface after modesetting, - * when running inside a VM. - */ - if (intel_vgpu_active(dev_priv)) - I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); - - /* Reveal our presence to userspace */ - if (drm_dev_register(dev, 0) == 0) { - i915_debugfs_register(dev_priv); - i915_setup_sysfs(dev); - } else - DRM_ERROR("Failed to register driver for userspace access!\n"); - - if (INTEL_INFO(dev_priv)->num_pipes) { - /* Must be done after probing outputs */ - intel_opregion_register(dev_priv); - acpi_video_register(); - } - - if (IS_GEN5(dev_priv)) - intel_gpu_ips_init(dev_priv); - - i915_audio_component_init(dev_priv); - - /* - * Some ports require correctly set-up hpd registers for detection to - * work properly (leading to ghost connected connector status), e.g. VGA - * on gm45. Hence we can only set up the initial fbdev config after hpd - * irqs are fully enabled. We do it last so that the async config - * cannot run before the connectors are registered. - */ - intel_fbdev_initial_config_async(dev); -} - -/** - * i915_driver_unregister - cleanup the registration done in i915_driver_regiser() - * @dev_priv: device private - */ -static void i915_driver_unregister(struct drm_i915_private *dev_priv) -{ - i915_audio_component_cleanup(dev_priv); - - intel_gpu_ips_teardown(); - acpi_video_unregister(); - intel_opregion_unregister(dev_priv); - - i915_teardown_sysfs(dev_priv->dev); - i915_debugfs_unregister(dev_priv); - drm_dev_unregister(dev_priv->dev); - - i915_gem_shrinker_cleanup(dev_priv); -} - -/** - * i915_driver_load - setup chip and create an initial config - * @dev: DRM device - * @flags: startup flags - * - * The driver load routine has to do several things: - * - drive output discovery via intel_modeset_init() - * - initialize the memory manager - * - allocate initial config memory - * - setup the DRM framebuffer with the allocated memory - */ -int i915_driver_load(struct pci_dev *pdev, - const struct pci_device_id *ent, - struct drm_driver *driver) -{ - struct drm_i915_private *dev_priv; - int ret; - - ret = -ENOMEM; - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); - if (dev_priv) - ret = drm_dev_init(&dev_priv->drm, driver, &pdev->dev); - if (ret) { - dev_printk(KERN_ERR, &pdev->dev, - "[" DRM_NAME ":%s] allocation failed\n", __func__); - kfree(dev_priv); - return ret; - } - - /* Must be set before calling __i915_printk */ - dev_priv->drm.pdev = pdev; - dev_priv->drm.dev_private = dev_priv; - dev_priv->dev = &dev_priv->drm; - - ret = pci_enable_device(pdev); - if (ret) - goto out_free_priv; - - pci_set_drvdata(pdev, &dev_priv->drm); - - ret = i915_driver_init_early(dev_priv, ent); - if (ret < 0) - goto out_pci_disable; - - intel_runtime_pm_get(dev_priv); - - ret = i915_driver_init_mmio(dev_priv); - if (ret < 0) - goto out_runtime_pm_put; - - ret = i915_driver_init_hw(dev_priv); - if (ret < 0) - goto out_cleanup_mmio; - - /* - * TODO: move the vblank init and parts of modeset init steps into one - * of the i915_driver_init_/i915_driver_register functions according - * to the role/effect of the given init step. - */ - if (INTEL_INFO(dev_priv)->num_pipes) { - ret = drm_vblank_init(dev_priv->dev, - INTEL_INFO(dev_priv)->num_pipes); - if (ret) - goto out_cleanup_hw; - } - - ret = i915_load_modeset_init(dev_priv->dev); - if (ret < 0) - goto out_cleanup_vblank; - - i915_driver_register(dev_priv); - - intel_runtime_pm_enable(dev_priv); - - intel_runtime_pm_put(dev_priv); - - return 0; - -out_cleanup_vblank: - drm_vblank_cleanup(dev_priv->dev); -out_cleanup_hw: - i915_driver_cleanup_hw(dev_priv); -out_cleanup_mmio: - i915_driver_cleanup_mmio(dev_priv); -out_runtime_pm_put: - intel_runtime_pm_put(dev_priv); - i915_driver_cleanup_early(dev_priv); -out_pci_disable: - pci_disable_device(pdev); -out_free_priv: - i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret); - drm_dev_unref(&dev_priv->drm); - return ret; -} - -int i915_driver_unload(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - intel_fbdev_fini(dev); - - intel_gvt_cleanup(dev_priv); - - ret = i915_gem_suspend(dev); - if (ret) { - DRM_ERROR("failed to idle hardware: %d\n", ret); - return ret; - } - - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); - - i915_driver_unregister(dev_priv); - - drm_vblank_cleanup(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; - - vga_switcheroo_unregister_client(dev->pdev); - vga_client_register(dev->pdev, NULL, NULL, NULL); - - intel_csr_ucode_fini(dev_priv); - - /* Free error state after interrupts are fully disabled. */ - cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); - i915_destroy_error_state(dev); - - /* Flush any outstanding unpin_work. */ - flush_workqueue(dev_priv->wq); - - intel_guc_fini(dev); - i915_gem_fini(dev); - intel_fbc_cleanup_cfb(dev_priv); - - intel_power_domains_fini(dev_priv); - - i915_driver_cleanup_hw(dev_priv); - i915_driver_cleanup_mmio(dev_priv); - - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); - - i915_driver_cleanup_early(dev_priv); - - return 0; -} - -int i915_driver_open(struct drm_device *dev, struct drm_file *file) -{ - int ret; - - ret = i915_gem_open(dev, file); - if (ret) - return ret; - - return 0; -} - -/** - * i915_driver_lastclose - clean up after all DRM clients have exited - * @dev: DRM device - * - * Take care of cleaning up after all DRM clients have exited. In the - * mode setting case, we want to restore the kernel's initial mode (just - * in case the last client left us in a bad state). - * - * Additionally, in the non-mode setting case, we'll tear down the GTT - * and DMA structures, since the kernel won't be using them, and clea - * up any GEM state. - */ -void i915_driver_lastclose(struct drm_device *dev) -{ - intel_fbdev_restore_mode(dev); - vga_switcheroo_process_delayed_switch(); -} - -void i915_driver_preclose(struct drm_device *dev, struct drm_file *file) -{ - mutex_lock(&dev->struct_mutex); - i915_gem_context_close(dev, file); - i915_gem_release(dev, file); - mutex_unlock(&dev->struct_mutex); -} - -void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) -{ - struct drm_i915_file_private *file_priv = file->driver_priv; - - kfree(file_priv); -} - -static int -i915_gem_reject_pin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file) -{ - return -ENODEV; -} - -const struct drm_ioctl_desc i915_ioctls[] = { - DRM_IOCTL_DEF_DRV(I915_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_FLUSH, drm_noop, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_FLIP, drm_noop, DRM_AUTH), - 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_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), - DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, drm_noop, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, drm_noop, DRM_AUTH), - 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, i915_gem_execbuffer2, 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), - DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, 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_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_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), - DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW), -}; - -int i915_max_ioctl = ARRAY_SIZE(i915_ioctls); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 9ddae6add9e0..e2375361a34d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -27,19 +27,29 @@ * */ -#include #include -#include -#include -#include "i915_drv.h" -#include "i915_trace.h" -#include "intel_drv.h" - #include +#include +#include #include +#include +#include #include +#include +#include +#include #include +#include +#include + +#include #include +#include + +#include "i915_drv.h" +#include "i915_trace.h" +#include "i915_vgpu.h" +#include "intel_drv.h" static struct drm_driver driver; @@ -321,239 +331,1833 @@ static const struct intel_device_info intel_broadwell_gt3m_info = { .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, }; -static const struct intel_device_info intel_cherryview_info = { - .gen = 8, .num_pipes = 3, - .need_gfx_hws = 1, .has_hotplug = 1, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, - .is_cherryview = 1, - .display_mmio_offset = VLV_DISPLAY_BASE, - GEN_CHV_PIPEOFFSETS, - CURSOR_OFFSETS, - CHV_COLORS, -}; +static const struct intel_device_info intel_cherryview_info = { + .gen = 8, .num_pipes = 3, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, + .is_cherryview = 1, + .display_mmio_offset = VLV_DISPLAY_BASE, + GEN_CHV_PIPEOFFSETS, + CURSOR_OFFSETS, + CHV_COLORS, +}; + +static const struct intel_device_info intel_skylake_info = { + BDW_FEATURES, + .is_skylake = 1, + .gen = 9, +}; + +static const struct intel_device_info intel_skylake_gt3_info = { + BDW_FEATURES, + .is_skylake = 1, + .gen = 9, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, +}; + +static const struct intel_device_info intel_broxton_info = { + .is_preliminary = 1, + .is_broxton = 1, + .gen = 9, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, + .num_pipes = 3, + .has_ddi = 1, + .has_fpga_dbg = 1, + .has_fbc = 1, + .has_pooled_eu = 0, + GEN_DEFAULT_PIPEOFFSETS, + IVB_CURSOR_OFFSETS, + BDW_COLORS, +}; + +static const struct intel_device_info intel_kabylake_info = { + BDW_FEATURES, + .is_kabylake = 1, + .gen = 9, +}; + +static const struct intel_device_info intel_kabylake_gt3_info = { + BDW_FEATURES, + .is_kabylake = 1, + .gen = 9, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, +}; + +/* + * Make sure any device matches here are from most specific to most + * general. For example, since the Quanta match is based on the subsystem + * and subvendor IDs, we need it to come before the more general IVB + * PCI ID matches, otherwise we'll use the wrong info struct above. + */ +static const struct pci_device_id pciidlist[] = { + INTEL_I830_IDS(&intel_i830_info), + INTEL_I845G_IDS(&intel_845g_info), + INTEL_I85X_IDS(&intel_i85x_info), + INTEL_I865G_IDS(&intel_i865g_info), + INTEL_I915G_IDS(&intel_i915g_info), + INTEL_I915GM_IDS(&intel_i915gm_info), + INTEL_I945G_IDS(&intel_i945g_info), + INTEL_I945GM_IDS(&intel_i945gm_info), + INTEL_I965G_IDS(&intel_i965g_info), + INTEL_G33_IDS(&intel_g33_info), + INTEL_I965GM_IDS(&intel_i965gm_info), + INTEL_GM45_IDS(&intel_gm45_info), + INTEL_G45_IDS(&intel_g45_info), + INTEL_PINEVIEW_IDS(&intel_pineview_info), + INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info), + INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info), + INTEL_SNB_D_IDS(&intel_sandybridge_d_info), + INTEL_SNB_M_IDS(&intel_sandybridge_m_info), + INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */ + INTEL_IVB_M_IDS(&intel_ivybridge_m_info), + INTEL_IVB_D_IDS(&intel_ivybridge_d_info), + INTEL_HSW_D_IDS(&intel_haswell_d_info), + INTEL_HSW_M_IDS(&intel_haswell_m_info), + INTEL_VLV_M_IDS(&intel_valleyview_m_info), + INTEL_VLV_D_IDS(&intel_valleyview_d_info), + INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info), + INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info), + INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), + INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), + INTEL_CHV_IDS(&intel_cherryview_info), + INTEL_SKL_GT1_IDS(&intel_skylake_info), + INTEL_SKL_GT2_IDS(&intel_skylake_info), + INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info), + INTEL_SKL_GT4_IDS(&intel_skylake_gt3_info), + INTEL_BXT_IDS(&intel_broxton_info), + INTEL_KBL_GT1_IDS(&intel_kabylake_info), + INTEL_KBL_GT2_IDS(&intel_kabylake_info), + INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info), + INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info), + {0, 0, 0} +}; +MODULE_DEVICE_TABLE(pci, pciidlist); + +static unsigned int i915_load_fail_count; + +bool __i915_inject_load_failure(const char *func, int line) +{ + if (i915_load_fail_count >= i915.inject_load_failure) + return false; + + if (++i915_load_fail_count == i915.inject_load_failure) { + DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n", + i915.inject_load_failure, func, line); + return true; + } + + return false; +} + +#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI" +#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \ + "providing the dmesg log by booting with drm.debug=0xf" + +void +__i915_printk(struct drm_i915_private *dev_priv, const char *level, + const char *fmt, ...) +{ + static bool shown_bug_once; + struct device *dev = dev_priv->dev->dev; + bool is_error = level[1] <= KERN_ERR[1]; + bool is_debug = level[1] == KERN_DEBUG[1]; + struct va_format vaf; + va_list args; + + if (is_debug && !(drm_debug & DRM_UT_DRIVER)) + return; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV", + __builtin_return_address(0), &vaf); + + if (is_error && !shown_bug_once) { + dev_notice(dev, "%s", FDO_BUG_MSG); + shown_bug_once = true; + } + + va_end(args); +} + +static bool i915_error_injected(struct drm_i915_private *dev_priv) +{ + return i915.inject_load_failure && + i915_load_fail_count == i915.inject_load_failure; +} + +#define i915_load_error(dev_priv, fmt, ...) \ + __i915_printk(dev_priv, \ + i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \ + fmt, ##__VA_ARGS__) + + +static enum intel_pch intel_virt_detect_pch(struct drm_device *dev) +{ + enum intel_pch ret = PCH_NOP; + + /* + * In a virtualized passthrough environment we can be in a + * setup where the ISA bridge is not able to be passed through. + * In this case, a south bridge can be emulated and we have to + * make an educated guess as to which PCH is really there. + */ + + if (IS_GEN5(dev)) { + ret = PCH_IBX; + DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n"); + } else if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { + ret = PCH_CPT; + DRM_DEBUG_KMS("Assuming CouarPoint PCH\n"); + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + ret = PCH_LPT; + DRM_DEBUG_KMS("Assuming LynxPoint PCH\n"); + } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { + ret = PCH_SPT; + DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n"); + } + + return ret; +} + +static void intel_detect_pch(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct pci_dev *pch = NULL; + + /* In all current cases, num_pipes is equivalent to the PCH_NOP setting + * (which really amounts to a PCH but no South Display). + */ + if (INTEL_INFO(dev)->num_pipes == 0) { + dev_priv->pch_type = PCH_NOP; + return; + } + + /* + * The reason to probe ISA bridge instead of Dev31:Fun0 is to + * make graphics device passthrough work easy for VMM, that only + * need to expose ISA bridge to let driver know the real hardware + * underneath. This is a requirement from virtualization team. + * + * In some virtualized environments (e.g. XEN), there is irrelevant + * ISA bridge in the system. To work reliably, we should scan trhough + * all the ISA bridge devices and check for the first match, instead + * of only checking the first one. + */ + while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) { + if (pch->vendor == PCI_VENDOR_ID_INTEL) { + unsigned short 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)); + } 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) || IS_IVYBRIDGE(dev))); + } 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) || IS_IVYBRIDGE(dev))); + } 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) && !IS_BROADWELL(dev)); + WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)); + } 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) && !IS_BROADWELL(dev)); + WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev)); + } 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) && + !IS_KABYLAKE(dev)); + } 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) && + !IS_KABYLAKE(dev)); + } 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); + } else + continue; + + break; + } + } + if (!pch) + DRM_DEBUG_KMS("No PCH found.\n"); + + pci_dev_put(pch); +} + +bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv) +{ + if (INTEL_GEN(dev_priv) < 6) + return false; + + if (i915.semaphores >= 0) + return i915.semaphores; + + /* TODO: make semaphores and Execlists play nicely together */ + if (i915.enable_execlists) + return false; + +#ifdef CONFIG_INTEL_IOMMU + /* Enable semaphores on SNB when IO remapping is off */ + if (IS_GEN6(dev_priv) && intel_iommu_gfx_mapped) + return false; +#endif + + return true; +} + +static int i915_getparam(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + drm_i915_getparam_t *param = data; + int value; + + switch (param->param) { + case I915_PARAM_IRQ_ACTIVE: + case I915_PARAM_ALLOW_BATCHBUFFER: + case I915_PARAM_LAST_DISPATCH: + /* Reject all old ums/dri params. */ + return -ENODEV; + case I915_PARAM_CHIPSET_ID: + value = dev->pdev->device; + break; + case I915_PARAM_REVISION: + value = dev->pdev->revision; + break; + case I915_PARAM_HAS_GEM: + value = 1; + break; + case I915_PARAM_NUM_FENCES_AVAIL: + value = dev_priv->num_fence_regs; + break; + case I915_PARAM_HAS_OVERLAY: + value = dev_priv->overlay ? 1 : 0; + break; + case I915_PARAM_HAS_PAGEFLIPPING: + value = 1; + break; + case I915_PARAM_HAS_EXECBUF2: + /* depends on GEM */ + value = 1; + break; + case I915_PARAM_HAS_BSD: + value = intel_engine_initialized(&dev_priv->engine[VCS]); + break; + case I915_PARAM_HAS_BLT: + value = intel_engine_initialized(&dev_priv->engine[BCS]); + break; + case I915_PARAM_HAS_VEBOX: + value = intel_engine_initialized(&dev_priv->engine[VECS]); + break; + case I915_PARAM_HAS_BSD2: + value = intel_engine_initialized(&dev_priv->engine[VCS2]); + break; + case I915_PARAM_HAS_RELAXED_FENCING: + value = 1; + break; + case I915_PARAM_HAS_COHERENT_RINGS: + value = 1; + break; + case I915_PARAM_HAS_EXEC_CONSTANTS: + value = INTEL_INFO(dev)->gen >= 4; + break; + case I915_PARAM_HAS_RELAXED_DELTA: + value = 1; + break; + case I915_PARAM_HAS_GEN7_SOL_RESET: + value = 1; + break; + case I915_PARAM_HAS_LLC: + value = HAS_LLC(dev); + break; + case I915_PARAM_HAS_WT: + value = HAS_WT(dev); + break; + case I915_PARAM_HAS_ALIASING_PPGTT: + value = USES_PPGTT(dev); + break; + case I915_PARAM_HAS_WAIT_TIMEOUT: + value = 1; + break; + case I915_PARAM_HAS_SEMAPHORES: + value = i915_semaphore_is_enabled(dev_priv); + break; + case I915_PARAM_HAS_PRIME_VMAP_FLUSH: + value = 1; + break; + case I915_PARAM_HAS_SECURE_BATCHES: + value = capable(CAP_SYS_ADMIN); + break; + case I915_PARAM_HAS_PINNED_BATCHES: + value = 1; + break; + case I915_PARAM_HAS_EXEC_NO_RELOC: + value = 1; + break; + case I915_PARAM_HAS_EXEC_HANDLE_LUT: + value = 1; + break; + case I915_PARAM_CMD_PARSER_VERSION: + value = i915_cmd_parser_get_version(dev_priv); + break; + case I915_PARAM_HAS_COHERENT_PHYS_GTT: + value = 1; + break; + case I915_PARAM_MMAP_VERSION: + value = 1; + break; + case I915_PARAM_SUBSLICE_TOTAL: + value = INTEL_INFO(dev)->subslice_total; + if (!value) + return -ENODEV; + break; + case I915_PARAM_EU_TOTAL: + value = INTEL_INFO(dev)->eu_total; + if (!value) + return -ENODEV; + break; + case I915_PARAM_HAS_GPU_RESET: + value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv); + break; + case I915_PARAM_HAS_RESOURCE_STREAMER: + value = HAS_RESOURCE_STREAMER(dev); + break; + case I915_PARAM_HAS_EXEC_SOFTPIN: + value = 1; + break; + default: + DRM_DEBUG("Unknown parameter %d\n", param->param); + return -EINVAL; + } + + if (copy_to_user(param->value, &value, sizeof(int))) { + DRM_ERROR("copy_to_user failed\n"); + return -EFAULT; + } + + return 0; +} + +static int i915_get_bridge_dev(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); + if (!dev_priv->bridge_dev) { + DRM_ERROR("bridge device not found\n"); + return -1; + } + return 0; +} + +/* Allocate space for the MCH regs if needed, return nonzero on error */ +static int +intel_alloc_mchbar_resource(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; + u32 temp_lo, temp_hi = 0; + u64 mchbar_addr; + int ret; + + if (INTEL_INFO(dev)->gen >= 4) + pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); + pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); + mchbar_addr = ((u64)temp_hi << 32) | temp_lo; + + /* If ACPI doesn't have it, assume we need to allocate it ourselves */ +#ifdef CONFIG_PNP + if (mchbar_addr && + pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) + return 0; +#endif + + /* Get some space for it */ + dev_priv->mch_res.name = "i915 MCHBAR"; + dev_priv->mch_res.flags = IORESOURCE_MEM; + ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, + &dev_priv->mch_res, + MCHBAR_SIZE, MCHBAR_SIZE, + PCIBIOS_MIN_MEM, + 0, pcibios_align_resource, + dev_priv->bridge_dev); + if (ret) { + DRM_DEBUG_DRIVER("failed bus alloc: %d\n", ret); + dev_priv->mch_res.start = 0; + return ret; + } + + if (INTEL_INFO(dev)->gen >= 4) + pci_write_config_dword(dev_priv->bridge_dev, reg + 4, + upper_32_bits(dev_priv->mch_res.start)); + + pci_write_config_dword(dev_priv->bridge_dev, reg, + lower_32_bits(dev_priv->mch_res.start)); + return 0; +} + +/* Setup MCHBAR if possible, return true if we should disable it again */ +static void +intel_setup_mchbar(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; + u32 temp; + bool enabled; + + if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) + return; + + dev_priv->mchbar_need_disable = false; + + if (IS_I915G(dev) || IS_I915GM(dev)) { + pci_read_config_dword(dev_priv->bridge_dev, DEVEN, &temp); + enabled = !!(temp & DEVEN_MCHBAR_EN); + } else { + pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); + enabled = temp & 1; + } + + /* If it's already enabled, don't have to do anything */ + if (enabled) + return; + + if (intel_alloc_mchbar_resource(dev)) + return; + + dev_priv->mchbar_need_disable = true; + + /* Space is allocated or reserved, so enable it. */ + if (IS_I915G(dev) || IS_I915GM(dev)) { + pci_write_config_dword(dev_priv->bridge_dev, DEVEN, + temp | DEVEN_MCHBAR_EN); + } else { + pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); + pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1); + } +} + +static void +intel_teardown_mchbar(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; + + if (dev_priv->mchbar_need_disable) { + if (IS_I915G(dev) || IS_I915GM(dev)) { + u32 deven_val; + + pci_read_config_dword(dev_priv->bridge_dev, DEVEN, + &deven_val); + deven_val &= ~DEVEN_MCHBAR_EN; + pci_write_config_dword(dev_priv->bridge_dev, DEVEN, + deven_val); + } else { + u32 mchbar_val; + + pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, + &mchbar_val); + mchbar_val &= ~1; + pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, + mchbar_val); + } + } + + if (dev_priv->mch_res.start) + release_resource(&dev_priv->mch_res); +} + +/* true = enable decode, false = disable decoder */ +static unsigned int i915_vga_set_decode(void *cookie, bool state) +{ + struct drm_device *dev = cookie; + + intel_modeset_vga_set_state(dev, state); + if (state) + return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | + VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; + else + return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; +} + +static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_state state) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; + + if (state == VGA_SWITCHEROO_ON) { + pr_info("switched on\n"); + dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; + /* i915 resume handler doesn't set to D0 */ + pci_set_power_state(dev->pdev, PCI_D0); + i915_resume_switcheroo(dev); + dev->switch_power_state = DRM_SWITCH_POWER_ON; + } else { + pr_info("switched off\n"); + dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; + i915_suspend_switcheroo(dev, pmm); + dev->switch_power_state = DRM_SWITCH_POWER_OFF; + } +} + +static bool i915_switcheroo_can_switch(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + /* + * FIXME: open_count is protected by drm_global_mutex but that would lead to + * locking inversion with the driver load path. And the access here is + * completely racy anyway. So don't bother with locking for now. + */ + return dev->open_count == 0; +} + +static const struct vga_switcheroo_client_ops i915_switcheroo_ops = { + .set_gpu_state = i915_switcheroo_set_state, + .reprobe = NULL, + .can_switch = i915_switcheroo_can_switch, +}; + +static void i915_gem_fini(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + + /* + * Neither the BIOS, ourselves or any other kernel + * expects the system to be in execlists mode on startup, + * so we need to reset the GPU back to legacy mode. And the only + * known way to disable logical contexts is through a GPU reset. + * + * So in order to leave the system in a known default configuration, + * always reset the GPU upon unload. Afterwards we then clean up the + * GEM state tracking, flushing off the requests and leaving the + * system in a known idle state. + * + * Note that is of the upmost importance that the GPU is idle and + * all stray writes are flushed *before* we dismantle the backing + * storage for the pinned objects. + * + * However, since we are uncertain that reseting the GPU on older + * machines is a good idea, we don't - just in case it leaves the + * machine in an unusable condition. + */ + if (HAS_HW_CONTEXTS(dev)) { + int reset = intel_gpu_reset(dev_priv, ALL_ENGINES); + WARN_ON(reset && reset != -ENODEV); + } + + mutex_lock(&dev->struct_mutex); + i915_gem_reset(dev); + i915_gem_cleanup_engines(dev); + i915_gem_context_fini(dev); + mutex_unlock(&dev->struct_mutex); + + WARN_ON(!list_empty(&to_i915(dev)->context_list)); +} + +static int i915_load_modeset_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + if (i915_inject_load_failure()) + return -ENODEV; + + ret = intel_bios_init(dev_priv); + if (ret) + DRM_INFO("failed to find VBIOS tables\n"); + + /* If we have > 1 VGA cards, then we need to arbitrate access + * to the common VGA resources. + * + * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA), + * then we do not take part in VGA arbitration and the + * vga_client_register() fails with -ENODEV. + */ + ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode); + if (ret && ret != -ENODEV) + goto out; + + intel_register_dsm_handler(); + + ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false); + if (ret) + goto cleanup_vga_client; + + /* must happen before intel_power_domains_init_hw() on VLV/CHV */ + intel_update_rawclk(dev_priv); + + intel_power_domains_init_hw(dev_priv, false); + + intel_csr_ucode_init(dev_priv); + + ret = intel_irq_install(dev_priv); + if (ret) + goto cleanup_csr; + + intel_setup_gmbus(dev); + + /* Important: The output setup functions called by modeset_init need + * working irqs for e.g. gmbus and dp aux transfers. */ + intel_modeset_init(dev); + + intel_guc_init(dev); + + ret = i915_gem_init(dev); + if (ret) + goto cleanup_irq; + + intel_modeset_gem_init(dev); + + if (INTEL_INFO(dev)->num_pipes == 0) + return 0; + + ret = intel_fbdev_init(dev); + if (ret) + goto cleanup_gem; + + /* Only enable hotplug handling once the fbdev is fully set up. */ + intel_hpd_init(dev_priv); + + drm_kms_helper_poll_init(dev); + + return 0; + +cleanup_gem: + i915_gem_fini(dev); +cleanup_irq: + intel_guc_fini(dev); + drm_irq_uninstall(dev); + intel_teardown_gmbus(dev); +cleanup_csr: + intel_csr_ucode_fini(dev_priv); + intel_power_domains_fini(dev_priv); + vga_switcheroo_unregister_client(dev->pdev); +cleanup_vga_client: + vga_client_register(dev->pdev, NULL, NULL, NULL); +out: + return ret; +} + +#if IS_ENABLED(CONFIG_FB) +static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) +{ + struct apertures_struct *ap; + struct pci_dev *pdev = dev_priv->dev->pdev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; + bool primary; + int ret; + + ap = alloc_apertures(1); + if (!ap) + return -ENOMEM; + + ap->ranges[0].base = ggtt->mappable_base; + ap->ranges[0].size = ggtt->mappable_end; + + primary = + pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; + + ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary); + + kfree(ap); + + return ret; +} +#else +static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) +{ + return 0; +} +#endif + +#if !defined(CONFIG_VGA_CONSOLE) +static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) +{ + return 0; +} +#elif !defined(CONFIG_DUMMY_CONSOLE) +static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) +{ + return -ENODEV; +} +#else +static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) +{ + int ret = 0; + + DRM_INFO("Replacing VGA console driver\n"); + + console_lock(); + if (con_is_bound(&vga_con)) + ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1); + if (ret == 0) { + ret = do_unregister_con_driver(&vga_con); + + /* Ignore "already unregistered". */ + if (ret == -ENODEV) + ret = 0; + } + console_unlock(); + + return ret; +} +#endif + +static void i915_dump_device_info(struct drm_i915_private *dev_priv) +{ + const struct intel_device_info *info = &dev_priv->info; + +#define PRINT_S(name) "%s" +#define SEP_EMPTY +#define PRINT_FLAG(name) info->name ? #name "," : "" +#define SEP_COMMA , + DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x rev=0x%02x flags=" + DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY), + info->gen, + dev_priv->dev->pdev->device, + dev_priv->dev->pdev->revision, + DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA)); +#undef PRINT_S +#undef SEP_EMPTY +#undef PRINT_FLAG +#undef SEP_COMMA +} + +static void cherryview_sseu_info_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_device_info *info; + u32 fuse, eu_dis; + + info = (struct intel_device_info *)&dev_priv->info; + fuse = I915_READ(CHV_FUSE_GT); + + info->slice_total = 1; + + if (!(fuse & CHV_FGT_DISABLE_SS0)) { + info->subslice_per_slice++; + eu_dis = fuse & (CHV_FGT_EU_DIS_SS0_R0_MASK | + CHV_FGT_EU_DIS_SS0_R1_MASK); + info->eu_total += 8 - hweight32(eu_dis); + } + + if (!(fuse & CHV_FGT_DISABLE_SS1)) { + info->subslice_per_slice++; + eu_dis = fuse & (CHV_FGT_EU_DIS_SS1_R0_MASK | + CHV_FGT_EU_DIS_SS1_R1_MASK); + info->eu_total += 8 - hweight32(eu_dis); + } + + info->subslice_total = info->subslice_per_slice; + /* + * CHV expected to always have a uniform distribution of EU + * across subslices. + */ + info->eu_per_subslice = info->subslice_total ? + info->eu_total / info->subslice_total : + 0; + /* + * CHV supports subslice power gating on devices with more than + * one subslice, and supports EU power gating on devices with + * more than one EU pair per subslice. + */ + info->has_slice_pg = 0; + info->has_subslice_pg = (info->subslice_total > 1); + info->has_eu_pg = (info->eu_per_subslice > 2); +} + +static void gen9_sseu_info_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_device_info *info; + int s_max = 3, ss_max = 4, eu_max = 8; + int s, ss; + u32 fuse2, s_enable, ss_disable, eu_disable; + u8 eu_mask = 0xff; + + info = (struct intel_device_info *)&dev_priv->info; + fuse2 = I915_READ(GEN8_FUSE2); + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> + GEN8_F2_S_ENA_SHIFT; + ss_disable = (fuse2 & GEN9_F2_SS_DIS_MASK) >> + GEN9_F2_SS_DIS_SHIFT; + + info->slice_total = hweight32(s_enable); + /* + * The subslice disable field is global, i.e. it applies + * to each of the enabled slices. + */ + info->subslice_per_slice = ss_max - hweight32(ss_disable); + info->subslice_total = info->slice_total * + info->subslice_per_slice; + + /* + * Iterate through enabled slices and subslices to + * count the total enabled EU. + */ + for (s = 0; s < s_max; s++) { + if (!(s_enable & (0x1 << s))) + /* skip disabled slice */ + continue; + + eu_disable = I915_READ(GEN9_EU_DISABLE(s)); + for (ss = 0; ss < ss_max; ss++) { + int eu_per_ss; + + if (ss_disable & (0x1 << ss)) + /* skip disabled subslice */ + continue; + + eu_per_ss = eu_max - hweight8((eu_disable >> (ss*8)) & + eu_mask); + + /* + * Record which subslice(s) has(have) 7 EUs. we + * can tune the hash used to spread work among + * subslices if they are unbalanced. + */ + if (eu_per_ss == 7) + info->subslice_7eu[s] |= 1 << ss; + + info->eu_total += eu_per_ss; + } + } + + /* + * SKL is expected to always have a uniform distribution + * of EU across subslices with the exception that any one + * EU in any one subslice may be fused off for die + * recovery. BXT is expected to be perfectly uniform in EU + * distribution. + */ + info->eu_per_subslice = info->subslice_total ? + DIV_ROUND_UP(info->eu_total, + info->subslice_total) : 0; + /* + * SKL supports slice power gating on devices with more than + * one slice, and supports EU power gating on devices with + * more than one EU pair per subslice. BXT supports subslice + * power gating on devices with more than one subslice, and + * supports EU power gating on devices with more than one EU + * pair per subslice. + */ + info->has_slice_pg = ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && + (info->slice_total > 1)); + info->has_subslice_pg = (IS_BROXTON(dev) && (info->subslice_total > 1)); + info->has_eu_pg = (info->eu_per_subslice > 2); + + if (IS_BROXTON(dev)) { +#define IS_SS_DISABLED(_ss_disable, ss) (_ss_disable & (0x1 << ss)) + /* + * There is a HW issue in 2x6 fused down parts that requires + * Pooled EU to be enabled as a WA. The pool configuration + * changes depending upon which subslice is fused down. This + * doesn't affect if the device has all 3 subslices enabled. + */ + /* WaEnablePooledEuFor2x6:bxt */ + info->has_pooled_eu = ((info->subslice_per_slice == 3) || + (info->subslice_per_slice == 2 && + INTEL_REVID(dev) < BXT_REVID_C0)); + + info->min_eu_in_pool = 0; + if (info->has_pooled_eu) { + if (IS_SS_DISABLED(ss_disable, 0) || + IS_SS_DISABLED(ss_disable, 2)) + info->min_eu_in_pool = 3; + else if (IS_SS_DISABLED(ss_disable, 1)) + info->min_eu_in_pool = 6; + else + info->min_eu_in_pool = 9; + } +#undef IS_SS_DISABLED + } +} + +static void broadwell_sseu_info_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_device_info *info; + const int s_max = 3, ss_max = 3, eu_max = 8; + int s, ss; + u32 fuse2, eu_disable[s_max], s_enable, ss_disable; + + fuse2 = I915_READ(GEN8_FUSE2); + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT; + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT; + + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK; + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) | + ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) << + (32 - GEN8_EU_DIS0_S1_SHIFT)); + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) | + ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) << + (32 - GEN8_EU_DIS1_S2_SHIFT)); + + + info = (struct intel_device_info *)&dev_priv->info; + info->slice_total = hweight32(s_enable); + + /* + * The subslice disable field is global, i.e. it applies + * to each of the enabled slices. + */ + info->subslice_per_slice = ss_max - hweight32(ss_disable); + info->subslice_total = info->slice_total * info->subslice_per_slice; + + /* + * Iterate through enabled slices and subslices to + * count the total enabled EU. + */ + for (s = 0; s < s_max; s++) { + if (!(s_enable & (0x1 << s))) + /* skip disabled slice */ + continue; + + for (ss = 0; ss < ss_max; ss++) { + u32 n_disabled; + + if (ss_disable & (0x1 << ss)) + /* skip disabled subslice */ + continue; + + n_disabled = hweight8(eu_disable[s] >> (ss * eu_max)); + + /* + * Record which subslices have 7 EUs. + */ + if (eu_max - n_disabled == 7) + info->subslice_7eu[s] |= 1 << ss; + + info->eu_total += eu_max - n_disabled; + } + } + + /* + * BDW is expected to always have a uniform distribution of EU across + * subslices with the exception that any one EU in any one subslice may + * be fused off for die recovery. + */ + info->eu_per_subslice = info->subslice_total ? + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0; + + /* + * BDW supports slice power gating on devices with more than + * one slice. + */ + info->has_slice_pg = (info->slice_total > 1); + info->has_subslice_pg = 0; + info->has_eu_pg = 0; +} + +/* + * Determine various intel_device_info fields at runtime. + * + * Use it when either: + * - it's judged too laborious to fill n static structures with the limit + * when a simple if statement does the job, + * - run-time checks (eg read fuse/strap registers) are needed. + * + * This function needs to be called: + * - after the MMIO has been setup as we are reading registers, + * - after the PCH has been detected, + * - before the first usage of the fields it can tweak. + */ +static void intel_device_info_runtime_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_device_info *info; + enum pipe pipe; + + info = (struct intel_device_info *)&dev_priv->info; + + /* + * Skylake and Broxton currently don't expose the topmost plane as its + * use is exclusive with the legacy cursor and we only want to expose + * one of those, not both. Until we can safely expose the topmost plane + * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported, + * we don't expose the topmost plane at all to prevent ABI breakage + * down the line. + */ + if (IS_BROXTON(dev)) { + info->num_sprites[PIPE_A] = 2; + info->num_sprites[PIPE_B] = 2; + info->num_sprites[PIPE_C] = 1; + } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) + for_each_pipe(dev_priv, pipe) + info->num_sprites[pipe] = 2; + else + for_each_pipe(dev_priv, pipe) + info->num_sprites[pipe] = 1; + + if (i915.disable_display) { + DRM_INFO("Display disabled (module parameter)\n"); + info->num_pipes = 0; + } else if (info->num_pipes > 0 && + (IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) && + HAS_PCH_SPLIT(dev)) { + u32 fuse_strap = I915_READ(FUSE_STRAP); + u32 sfuse_strap = I915_READ(SFUSE_STRAP); + + /* + * SFUSE_STRAP is supposed to have a bit signalling the display + * is fused off. Unfortunately it seems that, at least in + * certain cases, fused off display means that PCH display + * reads don't land anywhere. In that case, we read 0s. + * + * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK + * should be set when taking over after the firmware. + */ + if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE || + sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED || + (dev_priv->pch_type == PCH_CPT && + !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { + DRM_INFO("Display fused off, disabling\n"); + info->num_pipes = 0; + } else if (fuse_strap & IVB_PIPE_C_DISABLE) { + DRM_INFO("PipeC fused off\n"); + info->num_pipes -= 1; + } + } else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) { + u32 dfsm = I915_READ(SKL_DFSM); + u8 disabled_mask = 0; + bool invalid; + int num_bits; + + if (dfsm & SKL_DFSM_PIPE_A_DISABLE) + disabled_mask |= BIT(PIPE_A); + if (dfsm & SKL_DFSM_PIPE_B_DISABLE) + disabled_mask |= BIT(PIPE_B); + if (dfsm & SKL_DFSM_PIPE_C_DISABLE) + disabled_mask |= BIT(PIPE_C); + + num_bits = hweight8(disabled_mask); + + switch (disabled_mask) { + case BIT(PIPE_A): + case BIT(PIPE_B): + case BIT(PIPE_A) | BIT(PIPE_B): + case BIT(PIPE_A) | BIT(PIPE_C): + invalid = true; + break; + default: + invalid = false; + } + + if (num_bits > info->num_pipes || invalid) + DRM_ERROR("invalid pipe fuse configuration: 0x%x\n", + disabled_mask); + else + info->num_pipes -= num_bits; + } + + /* Initialize slice/subslice/EU info */ + if (IS_CHERRYVIEW(dev)) + cherryview_sseu_info_init(dev); + else if (IS_BROADWELL(dev)) + broadwell_sseu_info_init(dev); + else if (INTEL_INFO(dev)->gen >= 9) + gen9_sseu_info_init(dev); + + info->has_snoop = !info->has_llc; + + /* Snooping is broken on BXT A stepping. */ + if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) + info->has_snoop = false; + + DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total); + DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total); + DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice); + DRM_DEBUG_DRIVER("EU total: %u\n", info->eu_total); + DRM_DEBUG_DRIVER("EU per subslice: %u\n", info->eu_per_subslice); + DRM_DEBUG_DRIVER("has slice power gating: %s\n", + info->has_slice_pg ? "y" : "n"); + DRM_DEBUG_DRIVER("has subslice power gating: %s\n", + info->has_subslice_pg ? "y" : "n"); + DRM_DEBUG_DRIVER("has EU power gating: %s\n", + info->has_eu_pg ? "y" : "n"); + + i915.enable_execlists = + intel_sanitize_enable_execlists(dev_priv, + i915.enable_execlists); + + /* + * i915.enable_ppgtt is read-only, so do an early pass to validate the + * user's requested state against the hardware/driver capabilities. We + * do this now so that we can print out any log messages once rather + * than every time we check intel_enable_ppgtt(). + */ + i915.enable_ppgtt = + intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt); + DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt); +} + +static void intel_init_dpio(struct drm_i915_private *dev_priv) +{ + /* + * IOSF_PORT_DPIO is used for VLV x2 PHY (DP/HDMI B and C), + * CHV x1 PHY (DP/HDMI D) + * IOSF_PORT_DPIO_2 is used for CHV x2 PHY (DP/HDMI B and C) + */ + if (IS_CHERRYVIEW(dev_priv)) { + DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO_2; + DPIO_PHY_IOSF_PORT(DPIO_PHY1) = IOSF_PORT_DPIO; + } else if (IS_VALLEYVIEW(dev_priv)) { + DPIO_PHY_IOSF_PORT(DPIO_PHY0) = IOSF_PORT_DPIO; + } +} + +static int i915_workqueues_init(struct drm_i915_private *dev_priv) +{ + /* + * The i915 workqueue is primarily used for batched retirement of + * requests (and thus managing bo) once the task has been completed + * by the GPU. i915_gem_retire_requests() is called directly when we + * need high-priority retirement, such as waiting for an explicit + * bo. + * + * It is also used for periodic low-priority events, such as + * idle-timers and recording error state. + * + * All tasks on the workqueue are expected to acquire the dev mutex + * so there is no point in running more than one instance of the + * workqueue at any time. Use an ordered one. + */ + dev_priv->wq = alloc_ordered_workqueue("i915", 0); + if (dev_priv->wq == NULL) + goto out_err; + + dev_priv->hotplug.dp_wq = alloc_ordered_workqueue("i915-dp", 0); + if (dev_priv->hotplug.dp_wq == NULL) + goto out_free_wq; + + dev_priv->gpu_error.hangcheck_wq = + alloc_ordered_workqueue("i915-hangcheck", 0); + if (dev_priv->gpu_error.hangcheck_wq == NULL) + goto out_free_dp_wq; + + return 0; + +out_free_dp_wq: + destroy_workqueue(dev_priv->hotplug.dp_wq); +out_free_wq: + destroy_workqueue(dev_priv->wq); +out_err: + DRM_ERROR("Failed to allocate workqueues.\n"); + + return -ENOMEM; +} + +static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) +{ + destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); + destroy_workqueue(dev_priv->hotplug.dp_wq); + destroy_workqueue(dev_priv->wq); +} + +/** + * i915_driver_init_early - setup state not requiring device access + * @dev_priv: device private + * + * Initialize everything that is a "SW-only" state, that is state not + * requiring accessing the device or exposing the driver via kernel internal + * or userspace interfaces. Example steps belonging here: lock initialization, + * system memory allocation, setting up device specific attributes and + * function hooks not requiring accessing the device. + */ +static int i915_driver_init_early(struct drm_i915_private *dev_priv, + const struct pci_device_id *ent) +{ + const struct intel_device_info *match_info = + (struct intel_device_info *)ent->driver_data; + struct intel_device_info *device_info; + int ret = 0; + + if (i915_inject_load_failure()) + return -ENODEV; + + /* Setup the write-once "constant" device info */ + device_info = (struct intel_device_info *)&dev_priv->info; + memcpy(device_info, match_info, sizeof(*device_info)); + device_info->device_id = dev_priv->drm.pdev->device; + + 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); + spin_lock_init(&dev_priv->uncore.lock); + spin_lock_init(&dev_priv->mm.object_stat_lock); + spin_lock_init(&dev_priv->mmio_flip_lock); + mutex_init(&dev_priv->sb_lock); + mutex_init(&dev_priv->modeset_restore_lock); + mutex_init(&dev_priv->av_mutex); + mutex_init(&dev_priv->wm.wm_mutex); + mutex_init(&dev_priv->pps_mutex); + + ret = i915_workqueues_init(dev_priv); + if (ret < 0) + return ret; + + ret = intel_gvt_init(dev_priv); + if (ret < 0) + goto err_workqueues; + + /* This must be called before any calls to HAS_PCH_* */ + intel_detect_pch(&dev_priv->drm); + + intel_pm_setup(&dev_priv->drm); + intel_init_dpio(dev_priv); + intel_power_domains_init(dev_priv); + intel_irq_init(dev_priv); + intel_init_display_hooks(dev_priv); + intel_init_clock_gating_hooks(dev_priv); + intel_init_audio_hooks(dev_priv); + i915_gem_load_init(&dev_priv->drm); + + intel_display_crc_init(&dev_priv->drm); + + i915_dump_device_info(dev_priv); + + /* Not all pre-production machines fall into this category, only the + * very first ones. Almost everything should work, except for maybe + * suspend/resume. And we don't implement workarounds that affect only + * pre-production machines. */ + if (IS_HSW_EARLY_SDV(dev_priv)) + DRM_INFO("This is an early pre-production Haswell machine. " + "It may not be fully functional.\n"); + + return 0; + +err_workqueues: + i915_workqueues_cleanup(dev_priv); + return ret; +} + +/** + * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early() + * @dev_priv: device private + */ +static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) +{ + i915_gem_load_cleanup(dev_priv->dev); + i915_workqueues_cleanup(dev_priv); +} + +static int i915_mmio_setup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + int mmio_bar; + int mmio_size; + + mmio_bar = IS_GEN2(dev) ? 1 : 0; + /* + * Before gen4, the registers and the GTT are behind different BARs. + * However, from gen4 onwards, the registers and the GTT are shared + * in the same BAR, so we want to restrict this ioremap from + * clobbering the GTT which we want ioremap_wc instead. Fortunately, + * the register BAR remains the same size for all the earlier + * generations up to Ironlake. + */ + if (INTEL_INFO(dev)->gen < 5) + mmio_size = 512 * 1024; + else + mmio_size = 2 * 1024 * 1024; + dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, mmio_size); + if (dev_priv->regs == NULL) { + DRM_ERROR("failed to map registers\n"); + + return -EIO; + } + + /* Try to make sure MCHBAR is enabled before poking at it */ + intel_setup_mchbar(dev); + + return 0; +} + +static void i915_mmio_cleanup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = to_i915(dev); + + intel_teardown_mchbar(dev); + pci_iounmap(dev->pdev, dev_priv->regs); +} + +/** + * i915_driver_init_mmio - setup device MMIO + * @dev_priv: device private + * + * Setup minimal device state necessary for MMIO accesses later in the + * initialization sequence. The setup here should avoid any other device-wide + * side effects or exposing the driver via kernel internal or user space + * interfaces. + */ +static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + int ret; + + if (i915_inject_load_failure()) + return -ENODEV; + + if (i915_get_bridge_dev(dev)) + return -EIO; + + ret = i915_mmio_setup(dev); + if (ret < 0) + goto put_bridge; + + intel_uncore_init(dev_priv); + + return 0; + +put_bridge: + pci_dev_put(dev_priv->bridge_dev); + + return ret; +} + +/** + * i915_driver_cleanup_mmio - cleanup the setup done in i915_driver_init_mmio() + * @dev_priv: device private + */ +static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + intel_uncore_fini(dev_priv); + i915_mmio_cleanup(dev); + pci_dev_put(dev_priv->bridge_dev); +} + +/** + * i915_driver_init_hw - setup state requiring device access + * @dev_priv: device private + * + * Setup state that requires accessing the device, but doesn't require + * exposing the driver via kernel internal or userspace interfaces. + */ +static int i915_driver_init_hw(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; + uint32_t aperture_size; + int ret; + + if (i915_inject_load_failure()) + return -ENODEV; + + intel_device_info_runtime_init(dev); + + ret = i915_ggtt_init_hw(dev); + if (ret) + return ret; + + ret = i915_ggtt_enable_hw(dev); + if (ret) { + DRM_ERROR("failed to enable GGTT\n"); + goto out_ggtt; + } + + /* WARNING: Apparently we must kick fbdev drivers before vgacon, + * otherwise the vga fbdev driver falls over. */ + ret = i915_kick_out_firmware_fb(dev_priv); + if (ret) { + DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); + goto out_ggtt; + } + + ret = i915_kick_out_vgacon(dev_priv); + if (ret) { + DRM_ERROR("failed to remove conflicting VGA console\n"); + goto out_ggtt; + } + + pci_set_master(dev->pdev); + + /* overlay on gen2 is broken and can't address above 1G */ + if (IS_GEN2(dev)) { + ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); + if (ret) { + DRM_ERROR("failed to set DMA mask\n"); + + goto out_ggtt; + } + } + + + /* 965GM sometimes incorrectly writes to hardware status page (HWS) + * using 32bit addressing, overwriting memory if HWS is located + * above 4GB. + * + * The documentation also mentions an issue with undefined + * behaviour if any general state is accessed within a page above 4GB, + * which also needs to be handled carefully. + */ + if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) { + ret = dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); + + if (ret) { + DRM_ERROR("failed to set DMA mask\n"); + + goto out_ggtt; + } + } + + aperture_size = ggtt->mappable_end; + + ggtt->mappable = + io_mapping_create_wc(ggtt->mappable_base, + aperture_size); + if (!ggtt->mappable) { + ret = -EIO; + goto out_ggtt; + } + + ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base, + aperture_size); + + pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + + intel_uncore_sanitize(dev_priv); + + intel_opregion_setup(dev_priv); + + i915_gem_load_init_fences(dev_priv); + + /* On the 945G/GM, the chipset reports the MSI capability on the + * integrated graphics even though the support isn't actually there + * according to the published specs. It doesn't appear to function + * correctly in testing on 945G. + * This may be a side effect of MSI having been made available for PEG + * and the registers being closely associated. + * + * According to chipset errata, on the 965GM, MSI interrupts may + * be lost or delayed, but we use them anyways to avoid + * stuck interrupts on some machines. + */ + if (!IS_I945G(dev) && !IS_I945GM(dev)) { + if (pci_enable_msi(dev->pdev) < 0) + DRM_DEBUG_DRIVER("can't enable MSI"); + } + + return 0; + +out_ggtt: + i915_ggtt_cleanup_hw(dev); + + return ret; +} + +/** + * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw() + * @dev_priv: device private + */ +static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; + + if (dev->pdev->msi_enabled) + pci_disable_msi(dev->pdev); + + pm_qos_remove_request(&dev_priv->pm_qos); + arch_phys_wc_del(ggtt->mtrr); + io_mapping_free(ggtt->mappable); + i915_ggtt_cleanup_hw(dev); +} + +/** + * i915_driver_register - register the driver with the rest of the system + * @dev_priv: device private + * + * Perform any steps necessary to make the driver available via kernel + * internal or userspace interfaces. + */ +static void i915_driver_register(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + i915_gem_shrinker_init(dev_priv); + + /* + * Notify a valid surface after modesetting, + * when running inside a VM. + */ + if (intel_vgpu_active(dev_priv)) + I915_WRITE(vgtif_reg(display_ready), VGT_DRV_DISPLAY_READY); + + /* Reveal our presence to userspace */ + if (drm_dev_register(dev, 0) == 0) { + i915_debugfs_register(dev_priv); + i915_setup_sysfs(dev); + } else + DRM_ERROR("Failed to register driver for userspace access!\n"); + + if (INTEL_INFO(dev_priv)->num_pipes) { + /* Must be done after probing outputs */ + intel_opregion_register(dev_priv); + acpi_video_register(); + } + + if (IS_GEN5(dev_priv)) + intel_gpu_ips_init(dev_priv); + + i915_audio_component_init(dev_priv); + + /* + * Some ports require correctly set-up hpd registers for detection to + * work properly (leading to ghost connected connector status), e.g. VGA + * on gm45. Hence we can only set up the initial fbdev config after hpd + * irqs are fully enabled. We do it last so that the async config + * cannot run before the connectors are registered. + */ + intel_fbdev_initial_config_async(dev); +} + +/** + * i915_driver_unregister - cleanup the registration done in i915_driver_regiser() + * @dev_priv: device private + */ +static void i915_driver_unregister(struct drm_i915_private *dev_priv) +{ + i915_audio_component_cleanup(dev_priv); + + intel_gpu_ips_teardown(); + acpi_video_unregister(); + intel_opregion_unregister(dev_priv); + + i915_teardown_sysfs(dev_priv->dev); + i915_debugfs_unregister(dev_priv); + drm_dev_unregister(dev_priv->dev); + + i915_gem_shrinker_cleanup(dev_priv); +} + +/** + * i915_driver_load - setup chip and create an initial config + * @dev: DRM device + * @flags: startup flags + * + * The driver load routine has to do several things: + * - drive output discovery via intel_modeset_init() + * - initialize the memory manager + * - allocate initial config memory + * - setup the DRM framebuffer with the allocated memory + */ +static int i915_driver_load(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct drm_i915_private *dev_priv; + int ret; -static const struct intel_device_info intel_skylake_info = { - BDW_FEATURES, - .is_skylake = 1, - .gen = 9, -}; + ret = -ENOMEM; + dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); + if (dev_priv) + ret = drm_dev_init(&dev_priv->drm, &driver, &pdev->dev); + if (ret) { + dev_printk(KERN_ERR, &pdev->dev, + "[" DRM_NAME ":%s] allocation failed\n", __func__); + kfree(dev_priv); + return ret; + } -static const struct intel_device_info intel_skylake_gt3_info = { - BDW_FEATURES, - .is_skylake = 1, - .gen = 9, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, -}; + /* Must be set before calling __i915_printk */ + dev_priv->drm.pdev = pdev; + dev_priv->drm.dev_private = dev_priv; + dev_priv->dev = &dev_priv->drm; -static const struct intel_device_info intel_broxton_info = { - .is_preliminary = 1, - .is_broxton = 1, - .gen = 9, - .need_gfx_hws = 1, .has_hotplug = 1, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, - .num_pipes = 3, - .has_ddi = 1, - .has_fpga_dbg = 1, - .has_fbc = 1, - .has_pooled_eu = 0, - GEN_DEFAULT_PIPEOFFSETS, - IVB_CURSOR_OFFSETS, - BDW_COLORS, -}; + ret = pci_enable_device(pdev); + if (ret) + goto out_free_priv; -static const struct intel_device_info intel_kabylake_info = { - BDW_FEATURES, - .is_kabylake = 1, - .gen = 9, -}; + pci_set_drvdata(pdev, &dev_priv->drm); -static const struct intel_device_info intel_kabylake_gt3_info = { - BDW_FEATURES, - .is_kabylake = 1, - .gen = 9, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, -}; + ret = i915_driver_init_early(dev_priv, ent); + if (ret < 0) + goto out_pci_disable; -/* - * Make sure any device matches here are from most specific to most - * general. For example, since the Quanta match is based on the subsystem - * and subvendor IDs, we need it to come before the more general IVB - * PCI ID matches, otherwise we'll use the wrong info struct above. - */ -static const struct pci_device_id pciidlist[] = { - INTEL_I830_IDS(&intel_i830_info), - INTEL_I845G_IDS(&intel_845g_info), - INTEL_I85X_IDS(&intel_i85x_info), - INTEL_I865G_IDS(&intel_i865g_info), - INTEL_I915G_IDS(&intel_i915g_info), - INTEL_I915GM_IDS(&intel_i915gm_info), - INTEL_I945G_IDS(&intel_i945g_info), - INTEL_I945GM_IDS(&intel_i945gm_info), - INTEL_I965G_IDS(&intel_i965g_info), - INTEL_G33_IDS(&intel_g33_info), - INTEL_I965GM_IDS(&intel_i965gm_info), - INTEL_GM45_IDS(&intel_gm45_info), - INTEL_G45_IDS(&intel_g45_info), - INTEL_PINEVIEW_IDS(&intel_pineview_info), - INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info), - INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info), - INTEL_SNB_D_IDS(&intel_sandybridge_d_info), - INTEL_SNB_M_IDS(&intel_sandybridge_m_info), - INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */ - INTEL_IVB_M_IDS(&intel_ivybridge_m_info), - INTEL_IVB_D_IDS(&intel_ivybridge_d_info), - INTEL_HSW_D_IDS(&intel_haswell_d_info), - INTEL_HSW_M_IDS(&intel_haswell_m_info), - INTEL_VLV_M_IDS(&intel_valleyview_m_info), - INTEL_VLV_D_IDS(&intel_valleyview_d_info), - INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info), - INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info), - INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), - INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), - INTEL_CHV_IDS(&intel_cherryview_info), - INTEL_SKL_GT1_IDS(&intel_skylake_info), - INTEL_SKL_GT2_IDS(&intel_skylake_info), - INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info), - INTEL_SKL_GT4_IDS(&intel_skylake_gt3_info), - INTEL_BXT_IDS(&intel_broxton_info), - INTEL_KBL_GT1_IDS(&intel_kabylake_info), - INTEL_KBL_GT2_IDS(&intel_kabylake_info), - INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info), - INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info), - {0, 0, 0} -}; + intel_runtime_pm_get(dev_priv); -MODULE_DEVICE_TABLE(pci, pciidlist); + ret = i915_driver_init_mmio(dev_priv); + if (ret < 0) + goto out_runtime_pm_put; -static enum intel_pch intel_virt_detect_pch(struct drm_device *dev) -{ - enum intel_pch ret = PCH_NOP; + ret = i915_driver_init_hw(dev_priv); + if (ret < 0) + goto out_cleanup_mmio; /* - * In a virtualized passthrough environment we can be in a - * setup where the ISA bridge is not able to be passed through. - * In this case, a south bridge can be emulated and we have to - * make an educated guess as to which PCH is really there. + * TODO: move the vblank init and parts of modeset init steps into one + * of the i915_driver_init_/i915_driver_register functions according + * to the role/effect of the given init step. */ - - if (IS_GEN5(dev)) { - ret = PCH_IBX; - DRM_DEBUG_KMS("Assuming Ibex Peak PCH\n"); - } else if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { - ret = PCH_CPT; - DRM_DEBUG_KMS("Assuming CouarPoint PCH\n"); - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - ret = PCH_LPT; - DRM_DEBUG_KMS("Assuming LynxPoint PCH\n"); - } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { - ret = PCH_SPT; - DRM_DEBUG_KMS("Assuming SunrisePoint PCH\n"); + if (INTEL_INFO(dev_priv)->num_pipes) { + ret = drm_vblank_init(dev_priv->dev, + INTEL_INFO(dev_priv)->num_pipes); + if (ret) + goto out_cleanup_hw; } + ret = i915_load_modeset_init(dev_priv->dev); + if (ret < 0) + goto out_cleanup_vblank; + + i915_driver_register(dev_priv); + + intel_runtime_pm_enable(dev_priv); + + intel_runtime_pm_put(dev_priv); + + return 0; + +out_cleanup_vblank: + drm_vblank_cleanup(dev_priv->dev); +out_cleanup_hw: + i915_driver_cleanup_hw(dev_priv); +out_cleanup_mmio: + i915_driver_cleanup_mmio(dev_priv); +out_runtime_pm_put: + intel_runtime_pm_put(dev_priv); + i915_driver_cleanup_early(dev_priv); +out_pci_disable: + pci_disable_device(pdev); +out_free_priv: + i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret); + drm_dev_unref(&dev_priv->drm); return ret; } -void intel_detect_pch(struct drm_device *dev) +static int i915_driver_unload(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct pci_dev *pch = NULL; + int ret; - /* In all current cases, num_pipes is equivalent to the PCH_NOP setting - * (which really amounts to a PCH but no South Display). - */ - if (INTEL_INFO(dev)->num_pipes == 0) { - dev_priv->pch_type = PCH_NOP; - return; + intel_fbdev_fini(dev); + + ret = i915_gem_suspend(dev); + if (ret) { + DRM_ERROR("failed to idle hardware: %d\n", ret); + return ret; } + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); + + i915_driver_unregister(dev_priv); + + drm_vblank_cleanup(dev); + + intel_modeset_cleanup(dev); + /* - * The reason to probe ISA bridge instead of Dev31:Fun0 is to - * make graphics device passthrough work easy for VMM, that only - * need to expose ISA bridge to let driver know the real hardware - * underneath. This is a requirement from virtualization team. - * - * In some virtualized environments (e.g. XEN), there is irrelevant - * ISA bridge in the system. To work reliably, we should scan trhough - * all the ISA bridge devices and check for the first match, instead - * of only checking the first one. + * free the memory space allocated for the child device + * config parsed from VBT */ - while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) { - if (pch->vendor == PCI_VENDOR_ID_INTEL) { - unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK; - dev_priv->pch_id = id; + 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; - 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)); - } 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) || IS_IVYBRIDGE(dev))); - } 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) || IS_IVYBRIDGE(dev))); - } 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) && !IS_BROADWELL(dev)); - WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)); - } 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) && !IS_BROADWELL(dev)); - WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev)); - } 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) && - !IS_KABYLAKE(dev)); - } 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) && - !IS_KABYLAKE(dev)); - } 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); - } else - continue; + vga_switcheroo_unregister_client(dev->pdev); + vga_client_register(dev->pdev, NULL, NULL, NULL); - break; - } - } - if (!pch) - DRM_DEBUG_KMS("No PCH found.\n"); + intel_csr_ucode_fini(dev_priv); - pci_dev_put(pch); + /* Free error state after interrupts are fully disabled. */ + cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); + i915_destroy_error_state(dev); + + /* Flush any outstanding unpin_work. */ + flush_workqueue(dev_priv->wq); + + intel_guc_fini(dev); + i915_gem_fini(dev); + intel_fbc_cleanup_cfb(dev_priv); + + intel_power_domains_fini(dev_priv); + + i915_driver_cleanup_hw(dev_priv); + i915_driver_cleanup_mmio(dev_priv); + + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); + + i915_driver_cleanup_early(dev_priv); + + return 0; } -bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv) +static int i915_driver_open(struct drm_device *dev, struct drm_file *file) { - if (INTEL_GEN(dev_priv) < 6) - return false; + int ret; - if (i915.semaphores >= 0) - return i915.semaphores; + ret = i915_gem_open(dev, file); + if (ret) + return ret; - /* TODO: make semaphores and Execlists play nicely together */ - if (i915.enable_execlists) - return false; + return 0; +} -#ifdef CONFIG_INTEL_IOMMU - /* Enable semaphores on SNB when IO remapping is off */ - if (IS_GEN6(dev_priv) && intel_iommu_gfx_mapped) - return false; -#endif +/** + * i915_driver_lastclose - clean up after all DRM clients have exited + * @dev: DRM device + * + * Take care of cleaning up after all DRM clients have exited. In the + * mode setting case, we want to restore the kernel's initial mode (just + * in case the last client left us in a bad state). + * + * Additionally, in the non-mode setting case, we'll tear down the GTT + * and DMA structures, since the kernel won't be using them, and clea + * up any GEM state. + */ +static void i915_driver_lastclose(struct drm_device *dev) +{ + intel_fbdev_restore_mode(dev); + vga_switcheroo_process_delayed_switch(); +} - return true; +static void i915_driver_preclose(struct drm_device *dev, struct drm_file *file) +{ + mutex_lock(&dev->struct_mutex); + i915_gem_context_close(dev, file); + i915_gem_release(dev, file); + mutex_unlock(&dev->struct_mutex); +} + +static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) +{ + struct drm_i915_file_private *file_priv = file->driver_priv; + + kfree(file_priv); } static void intel_suspend_encoders(struct drm_i915_private *dev_priv) @@ -1034,7 +2638,7 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (vga_switcheroo_client_probe_defer(pdev)) return -EPROBE_DEFER; - return i915_driver_load(pdev, ent, &driver); + return i915_driver_load(pdev, ent); } static void @@ -1742,6 +3346,68 @@ static const struct file_operations i915_driver_fops = { .llseek = noop_llseek, }; +static int +i915_gem_reject_pin_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + return -ENODEV; +} + +static const struct drm_ioctl_desc i915_ioctls[] = { + DRM_IOCTL_DEF_DRV(I915_INIT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_FLUSH, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_FLIP, drm_noop, DRM_AUTH), + 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_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), + DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, drm_noop, DRM_AUTH), + 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, i915_gem_execbuffer2, 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), + DRM_IOCTL_DEF_DRV(I915_GEM_SET_CACHING, i915_gem_set_caching_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_GET_CACHING, i915_gem_get_caching_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, 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_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_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), + DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW), +}; + static struct drm_driver driver = { /* Don't use MTRRs here; the Xserver or userspace app should * deal with them for Intel hardware. @@ -1767,6 +3433,7 @@ static struct drm_driver driver = { .dumb_map_offset = i915_gem_mmap_gtt, .dumb_destroy = drm_gem_dumb_destroy, .ioctls = i915_ioctls, + .num_ioctls = ARRAY_SIZE(i915_ioctls), .fops = &i915_driver_fops, .name = DRIVER_NAME, .desc = DRIVER_DESC, @@ -1786,8 +3453,6 @@ static struct pci_driver i915_pci_driver = { static int __init i915_init(void) { - driver.num_ioctls = i915_max_ioctl; - /* * Enable KMS by default, unless explicitly overriden by * either the i915.modeset prarameter or by the diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e0fc47b8b7ee..5b68c07b3921 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2894,16 +2894,13 @@ struct drm_i915_cmd_table { #include "i915_trace.h" -extern const struct drm_ioctl_desc i915_ioctls[]; -extern int i915_max_ioctl; - extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state); extern int i915_resume_switcheroo(struct drm_device *dev); int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, int enable_ppgtt); -/* i915_dma.c */ +/* i915_drv.c */ void __printf(3, 4) __i915_printk(struct drm_i915_private *dev_priv, const char *level, const char *fmt, ...); @@ -2911,16 +2908,6 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level, #define i915_report_error(dev_priv, fmt, ...) \ __i915_printk(dev_priv, KERN_ERR, fmt, ##__VA_ARGS__) -extern int i915_driver_load(struct pci_dev *pdev, - const struct pci_device_id *ent, - struct drm_driver *driver); -extern int i915_driver_unload(struct drm_device *); -extern int i915_driver_open(struct drm_device *dev, struct drm_file *file); -extern void i915_driver_lastclose(struct drm_device * dev); -extern void i915_driver_preclose(struct drm_device *dev, - struct drm_file *file); -extern void i915_driver_postclose(struct drm_device *dev, - struct drm_file *file); #ifdef CONFIG_COMPAT extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); @@ -3751,7 +3738,6 @@ extern void intel_init_pch_refclk(struct drm_device *dev); extern void intel_set_rps(struct drm_i915_private *dev_priv, u8 val); extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable); -extern void intel_detect_pch(struct drm_device *dev); extern bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv); int i915_reg_read_ioctl(struct drm_device *dev, void *data, -- cgit v1.2.3 From dda330099afc10160d1ae1f74838f8452169dbbd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:23 +0100 Subject: drm/i915: Remove user controllable DRM_ERROR for i915_getparam() The GETPARAM ioctl writes to a user supplied address. If that address is invalid, it is the user's error and not the driver's, so quietly report EFAULT and don't blame ourselves with a DRM_ERROR. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-11-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e2375361a34d..afa3e99fd48a 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -752,10 +752,8 @@ static int i915_getparam(struct drm_device *dev, void *data, return -EINVAL; } - if (copy_to_user(param->value, &value, sizeof(int))) { - DRM_ERROR("copy_to_user failed\n"); + if (put_user(value, param->value)) return -EFAULT; - } return 0; } -- cgit v1.2.3 From 71240ed20df09e60f13db951dc9573168f5fd71e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:24 +0100 Subject: drm/i915: Remove user controllable DRM_ERROR for intel_get_pipe_from_crtc_id() Don't emit a driver DRM_ERROR for a user passing in an invalid CRTC id, simply report it is missing back to the user. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-12-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c3257177d527..c3b5dc8f5e80 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14633,11 +14633,8 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct intel_crtc *crtc; drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id); - - if (!drmmode_crtc) { - DRM_ERROR("no such CRTC id\n"); + if (!drmmode_crtc) return -ENOENT; - } crtc = to_intel_crtc(drmmode_crtc); pipe_from_crtc_id->pipe = crtc->pipe; -- cgit v1.2.3 From c2dac8680ee49b0dc870b3d7b23c5102d3e49eb9 Mon Sep 17 00:00:00 2001 From: Frank Binns Date: Fri, 24 Jun 2016 14:00:25 +0100 Subject: drm/i915: Fix misleading driver debug message Stop claiming that UMS support is disabled when it's not actually supported anymore. Signed-off-by: Frank Binns Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1466763836-27772-1-git-send-email-frank.binns@imgtec.com Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-13-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index afa3e99fd48a..50d1a71aeddc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -3465,7 +3465,7 @@ static int __init i915_init(void) if (!(driver.driver_features & DRIVER_MODESET)) { /* Silently fail loading to not upset userspace. */ - DRM_DEBUG_DRIVER("KMS and UMS disabled.\n"); + DRM_DEBUG_DRIVER("KMS disabled.\n"); return 0; } -- cgit v1.2.3 From 42f5551d276921d4de8bd45765494b2dc63eb39c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:26 +0100 Subject: drm/i915: Split out the PCI driver interface to i915_pci.c To reclaim a bit of space from i915_drv.c, we can move the routines that just hook us into the PCI device tree into i915_pci.c Signed-off-by: Chris Wilson Cc: Daniel Vetter Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-14-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.c | 444 +------------------------------------- drivers/gpu/drm/i915/i915_pci.c | 461 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 471 insertions(+), 435 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_pci.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index c07cfb649f32..a3d2b789c9ec 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -10,6 +10,7 @@ subdir-ccflags-$(CONFIG_DRM_I915_WERROR) := -Werror i915-y := i915_drv.o \ i915_irq.o \ i915_params.o \ + i915_pci.o \ i915_suspend.o \ i915_sysfs.o \ intel_csr.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 50d1a71aeddc..7d011a686bc9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -53,387 +53,6 @@ static struct drm_driver driver; -#define GEN_DEFAULT_PIPEOFFSETS \ - .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ - PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \ - .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ - TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \ - .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET } - -#define GEN_CHV_PIPEOFFSETS \ - .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ - CHV_PIPE_C_OFFSET }, \ - .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ - CHV_TRANSCODER_C_OFFSET, }, \ - .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET, \ - CHV_PALETTE_C_OFFSET } - -#define CURSOR_OFFSETS \ - .cursor_offsets = { CURSOR_A_OFFSET, CURSOR_B_OFFSET, CHV_CURSOR_C_OFFSET } - -#define IVB_CURSOR_OFFSETS \ - .cursor_offsets = { CURSOR_A_OFFSET, IVB_CURSOR_B_OFFSET, IVB_CURSOR_C_OFFSET } - -#define BDW_COLORS \ - .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } -#define CHV_COLORS \ - .color = { .degamma_lut_size = 65, .gamma_lut_size = 257 } - -static const struct intel_device_info intel_i830_info = { - .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, - .has_overlay = 1, .overlay_needs_physical = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_845g_info = { - .gen = 2, .num_pipes = 1, - .has_overlay = 1, .overlay_needs_physical = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_i85x_info = { - .gen = 2, .is_i85x = 1, .is_mobile = 1, .num_pipes = 2, - .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, - .has_fbc = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_i865g_info = { - .gen = 2, .num_pipes = 1, - .has_overlay = 1, .overlay_needs_physical = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_i915g_info = { - .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2, - .has_overlay = 1, .overlay_needs_physical = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; -static const struct intel_device_info intel_i915gm_info = { - .gen = 3, .is_mobile = 1, .num_pipes = 2, - .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, - .supports_tv = 1, - .has_fbc = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; -static const struct intel_device_info intel_i945g_info = { - .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2, - .has_overlay = 1, .overlay_needs_physical = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; -static const struct intel_device_info intel_i945gm_info = { - .gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2, - .has_hotplug = 1, .cursor_needs_physical = 1, - .has_overlay = 1, .overlay_needs_physical = 1, - .supports_tv = 1, - .has_fbc = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_i965g_info = { - .gen = 4, .is_broadwater = 1, .num_pipes = 2, - .has_hotplug = 1, - .has_overlay = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_i965gm_info = { - .gen = 4, .is_crestline = 1, .num_pipes = 2, - .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, - .has_overlay = 1, - .supports_tv = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_g33_info = { - .gen = 3, .is_g33 = 1, .num_pipes = 2, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_overlay = 1, - .ring_mask = RENDER_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_g45_info = { - .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2, - .has_pipe_cxsr = 1, .has_hotplug = 1, - .ring_mask = RENDER_RING | BSD_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_gm45_info = { - .gen = 4, .is_g4x = 1, .num_pipes = 2, - .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, - .has_pipe_cxsr = 1, .has_hotplug = 1, - .supports_tv = 1, - .ring_mask = RENDER_RING | BSD_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_pineview_info = { - .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .num_pipes = 2, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_overlay = 1, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_ironlake_d_info = { - .gen = 5, .num_pipes = 2, - .need_gfx_hws = 1, .has_hotplug = 1, - .ring_mask = RENDER_RING | BSD_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_ironlake_m_info = { - .gen = 5, .is_mobile = 1, .num_pipes = 2, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_fbc = 1, - .ring_mask = RENDER_RING | BSD_RING, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_sandybridge_d_info = { - .gen = 6, .num_pipes = 2, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_fbc = 1, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING, - .has_llc = 1, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -static const struct intel_device_info intel_sandybridge_m_info = { - .gen = 6, .is_mobile = 1, .num_pipes = 2, - .need_gfx_hws = 1, .has_hotplug = 1, - .has_fbc = 1, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING, - .has_llc = 1, - GEN_DEFAULT_PIPEOFFSETS, - CURSOR_OFFSETS, -}; - -#define GEN7_FEATURES \ - .gen = 7, .num_pipes = 3, \ - .need_gfx_hws = 1, .has_hotplug = 1, \ - .has_fbc = 1, \ - .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ - .has_llc = 1, \ - GEN_DEFAULT_PIPEOFFSETS, \ - IVB_CURSOR_OFFSETS - -static const struct intel_device_info intel_ivybridge_d_info = { - GEN7_FEATURES, - .is_ivybridge = 1, -}; - -static const struct intel_device_info intel_ivybridge_m_info = { - GEN7_FEATURES, - .is_ivybridge = 1, - .is_mobile = 1, -}; - -static const struct intel_device_info intel_ivybridge_q_info = { - GEN7_FEATURES, - .is_ivybridge = 1, - .num_pipes = 0, /* legal, last one wins */ -}; - -#define VLV_FEATURES \ - .gen = 7, .num_pipes = 2, \ - .need_gfx_hws = 1, .has_hotplug = 1, \ - .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ - .display_mmio_offset = VLV_DISPLAY_BASE, \ - GEN_DEFAULT_PIPEOFFSETS, \ - CURSOR_OFFSETS - -static const struct intel_device_info intel_valleyview_m_info = { - VLV_FEATURES, - .is_valleyview = 1, - .is_mobile = 1, -}; - -static const struct intel_device_info intel_valleyview_d_info = { - VLV_FEATURES, - .is_valleyview = 1, -}; - -#define HSW_FEATURES \ - GEN7_FEATURES, \ - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \ - .has_ddi = 1, \ - .has_fpga_dbg = 1 - -static const struct intel_device_info intel_haswell_d_info = { - HSW_FEATURES, - .is_haswell = 1, -}; - -static const struct intel_device_info intel_haswell_m_info = { - HSW_FEATURES, - .is_haswell = 1, - .is_mobile = 1, -}; - -#define BDW_FEATURES \ - HSW_FEATURES, \ - BDW_COLORS - -static const struct intel_device_info intel_broadwell_d_info = { - BDW_FEATURES, - .gen = 8, - .is_broadwell = 1, -}; - -static const struct intel_device_info intel_broadwell_m_info = { - BDW_FEATURES, - .gen = 8, .is_mobile = 1, - .is_broadwell = 1, -}; - -static const struct intel_device_info intel_broadwell_gt3d_info = { - BDW_FEATURES, - .gen = 8, - .is_broadwell = 1, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, -}; - -static const struct intel_device_info intel_broadwell_gt3m_info = { - BDW_FEATURES, - .gen = 8, .is_mobile = 1, - .is_broadwell = 1, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, -}; - -static const struct intel_device_info intel_cherryview_info = { - .gen = 8, .num_pipes = 3, - .need_gfx_hws = 1, .has_hotplug = 1, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, - .is_cherryview = 1, - .display_mmio_offset = VLV_DISPLAY_BASE, - GEN_CHV_PIPEOFFSETS, - CURSOR_OFFSETS, - CHV_COLORS, -}; - -static const struct intel_device_info intel_skylake_info = { - BDW_FEATURES, - .is_skylake = 1, - .gen = 9, -}; - -static const struct intel_device_info intel_skylake_gt3_info = { - BDW_FEATURES, - .is_skylake = 1, - .gen = 9, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, -}; - -static const struct intel_device_info intel_broxton_info = { - .is_preliminary = 1, - .is_broxton = 1, - .gen = 9, - .need_gfx_hws = 1, .has_hotplug = 1, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, - .num_pipes = 3, - .has_ddi = 1, - .has_fpga_dbg = 1, - .has_fbc = 1, - .has_pooled_eu = 0, - GEN_DEFAULT_PIPEOFFSETS, - IVB_CURSOR_OFFSETS, - BDW_COLORS, -}; - -static const struct intel_device_info intel_kabylake_info = { - BDW_FEATURES, - .is_kabylake = 1, - .gen = 9, -}; - -static const struct intel_device_info intel_kabylake_gt3_info = { - BDW_FEATURES, - .is_kabylake = 1, - .gen = 9, - .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, -}; - -/* - * Make sure any device matches here are from most specific to most - * general. For example, since the Quanta match is based on the subsystem - * and subvendor IDs, we need it to come before the more general IVB - * PCI ID matches, otherwise we'll use the wrong info struct above. - */ -static const struct pci_device_id pciidlist[] = { - INTEL_I830_IDS(&intel_i830_info), - INTEL_I845G_IDS(&intel_845g_info), - INTEL_I85X_IDS(&intel_i85x_info), - INTEL_I865G_IDS(&intel_i865g_info), - INTEL_I915G_IDS(&intel_i915g_info), - INTEL_I915GM_IDS(&intel_i915gm_info), - INTEL_I945G_IDS(&intel_i945g_info), - INTEL_I945GM_IDS(&intel_i945gm_info), - INTEL_I965G_IDS(&intel_i965g_info), - INTEL_G33_IDS(&intel_g33_info), - INTEL_I965GM_IDS(&intel_i965gm_info), - INTEL_GM45_IDS(&intel_gm45_info), - INTEL_G45_IDS(&intel_g45_info), - INTEL_PINEVIEW_IDS(&intel_pineview_info), - INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info), - INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info), - INTEL_SNB_D_IDS(&intel_sandybridge_d_info), - INTEL_SNB_M_IDS(&intel_sandybridge_m_info), - INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */ - INTEL_IVB_M_IDS(&intel_ivybridge_m_info), - INTEL_IVB_D_IDS(&intel_ivybridge_d_info), - INTEL_HSW_D_IDS(&intel_haswell_d_info), - INTEL_HSW_M_IDS(&intel_haswell_m_info), - INTEL_VLV_M_IDS(&intel_valleyview_m_info), - INTEL_VLV_D_IDS(&intel_valleyview_d_info), - INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info), - INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info), - INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), - INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), - INTEL_CHV_IDS(&intel_cherryview_info), - INTEL_SKL_GT1_IDS(&intel_skylake_info), - INTEL_SKL_GT2_IDS(&intel_skylake_info), - INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info), - INTEL_SKL_GT4_IDS(&intel_skylake_gt3_info), - INTEL_BXT_IDS(&intel_broxton_info), - INTEL_KBL_GT1_IDS(&intel_kabylake_info), - INTEL_KBL_GT2_IDS(&intel_kabylake_info), - INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info), - INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info), - {0, 0, 0} -}; -MODULE_DEVICE_TABLE(pci, pciidlist); - static unsigned int i915_load_fail_count; bool __i915_inject_load_failure(const char *func, int line) @@ -1968,8 +1587,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) * - allocate initial config memory * - setup the DRM framebuffer with the allocated memory */ -static int i915_driver_load(struct pci_dev *pdev, - const struct pci_device_id *ent) +int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) { struct drm_i915_private *dev_priv; int ret; @@ -2051,18 +1669,14 @@ out_free_priv: return ret; } -static int i915_driver_unload(struct drm_device *dev) +void i915_driver_unload(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int ret; intel_fbdev_fini(dev); - ret = i915_gem_suspend(dev); - if (ret) { - DRM_ERROR("failed to idle hardware: %d\n", ret); - return ret; - } + if (i915_gem_suspend(dev)) + DRM_ERROR("failed to idle hardware; continuing to unload!\n"); intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); @@ -2110,8 +1724,6 @@ static int i915_driver_unload(struct drm_device *dev) intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); i915_driver_cleanup_early(dev_priv); - - return 0; } static int i915_driver_open(struct drm_device *dev, struct drm_file *file) @@ -2614,40 +2226,6 @@ error: return ret; } -static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct intel_device_info *intel_info = - (struct intel_device_info *) ent->driver_data; - - if (IS_PRELIMINARY_HW(intel_info) && !i915.preliminary_hw_support) { - DRM_INFO("This hardware requires preliminary hardware support.\n" - "See CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT, and/or modparam preliminary_hw_support\n"); - return -ENODEV; - } - - /* Only bind to function 0 of the device. Early generations - * used function 1 as a placeholder for multi-head. This causes - * us confusion instead, especially on the systems where both - * functions have the same PCI-ID! - */ - if (PCI_FUNC(pdev->devfn)) - return -ENODEV; - - if (vga_switcheroo_client_probe_defer(pdev)) - return -EPROBE_DEFER; - - return i915_driver_load(pdev, ent); -} - -static void -i915_pci_remove(struct pci_dev *pdev) -{ - struct drm_device *dev = pci_get_drvdata(pdev); - - i915_driver_unload(dev); - drm_dev_unref(dev); -} - static int i915_pm_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); @@ -3285,7 +2863,7 @@ static int intel_runtime_resume(struct device *device) return ret; } -static const struct dev_pm_ops i915_pm_ops = { +const struct dev_pm_ops i915_pm_ops = { /* * S0ix (via system suspend) and S3 event handlers [PMSG_SUSPEND, * PMSG_RESUME] @@ -3441,16 +3019,10 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, }; -static struct pci_driver i915_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .probe = i915_pci_probe, - .remove = i915_pci_remove, - .driver.pm = &i915_pm_ops, -}; - static int __init i915_init(void) { + extern struct pci_driver i915_pci_driver; + /* * Enable KMS by default, unless explicitly overriden by * either the i915.modeset prarameter or by the @@ -3477,6 +3049,8 @@ static int __init i915_init(void) static void __exit i915_exit(void) { + extern struct pci_driver i915_pci_driver; + if (!(driver.driver_features & DRIVER_MODESET)) return; /* Never loaded a driver. */ diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c new file mode 100644 index 000000000000..9aa07f38caea --- /dev/null +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -0,0 +1,461 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, 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. + * + */ + +#include +#include + +#include "i915_drv.h" + +#define GEN_DEFAULT_PIPEOFFSETS \ + .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ + PIPE_C_OFFSET, PIPE_EDP_OFFSET }, \ + .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ + TRANSCODER_C_OFFSET, TRANSCODER_EDP_OFFSET }, \ + .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET } + +#define GEN_CHV_PIPEOFFSETS \ + .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \ + CHV_PIPE_C_OFFSET }, \ + .trans_offsets = { TRANSCODER_A_OFFSET, TRANSCODER_B_OFFSET, \ + CHV_TRANSCODER_C_OFFSET, }, \ + .palette_offsets = { PALETTE_A_OFFSET, PALETTE_B_OFFSET, \ + CHV_PALETTE_C_OFFSET } + +#define CURSOR_OFFSETS \ + .cursor_offsets = { CURSOR_A_OFFSET, CURSOR_B_OFFSET, CHV_CURSOR_C_OFFSET } + +#define IVB_CURSOR_OFFSETS \ + .cursor_offsets = { CURSOR_A_OFFSET, IVB_CURSOR_B_OFFSET, IVB_CURSOR_C_OFFSET } + +#define BDW_COLORS \ + .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } +#define CHV_COLORS \ + .color = { .degamma_lut_size = 65, .gamma_lut_size = 257 } + +static const struct intel_device_info intel_i830_info = { + .gen = 2, .is_mobile = 1, .cursor_needs_physical = 1, .num_pipes = 2, + .has_overlay = 1, .overlay_needs_physical = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_845g_info = { + .gen = 2, .num_pipes = 1, + .has_overlay = 1, .overlay_needs_physical = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_i85x_info = { + .gen = 2, .is_i85x = 1, .is_mobile = 1, .num_pipes = 2, + .cursor_needs_physical = 1, + .has_overlay = 1, .overlay_needs_physical = 1, + .has_fbc = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_i865g_info = { + .gen = 2, .num_pipes = 1, + .has_overlay = 1, .overlay_needs_physical = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_i915g_info = { + .gen = 3, .is_i915g = 1, .cursor_needs_physical = 1, .num_pipes = 2, + .has_overlay = 1, .overlay_needs_physical = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; +static const struct intel_device_info intel_i915gm_info = { + .gen = 3, .is_mobile = 1, .num_pipes = 2, + .cursor_needs_physical = 1, + .has_overlay = 1, .overlay_needs_physical = 1, + .supports_tv = 1, + .has_fbc = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; +static const struct intel_device_info intel_i945g_info = { + .gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1, .num_pipes = 2, + .has_overlay = 1, .overlay_needs_physical = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; +static const struct intel_device_info intel_i945gm_info = { + .gen = 3, .is_i945gm = 1, .is_mobile = 1, .num_pipes = 2, + .has_hotplug = 1, .cursor_needs_physical = 1, + .has_overlay = 1, .overlay_needs_physical = 1, + .supports_tv = 1, + .has_fbc = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_i965g_info = { + .gen = 4, .is_broadwater = 1, .num_pipes = 2, + .has_hotplug = 1, + .has_overlay = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_i965gm_info = { + .gen = 4, .is_crestline = 1, .num_pipes = 2, + .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, + .has_overlay = 1, + .supports_tv = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_g33_info = { + .gen = 3, .is_g33 = 1, .num_pipes = 2, + .need_gfx_hws = 1, .has_hotplug = 1, + .has_overlay = 1, + .ring_mask = RENDER_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_g45_info = { + .gen = 4, .is_g4x = 1, .need_gfx_hws = 1, .num_pipes = 2, + .has_pipe_cxsr = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_gm45_info = { + .gen = 4, .is_g4x = 1, .num_pipes = 2, + .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, + .has_pipe_cxsr = 1, .has_hotplug = 1, + .supports_tv = 1, + .ring_mask = RENDER_RING | BSD_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_pineview_info = { + .gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .num_pipes = 2, + .need_gfx_hws = 1, .has_hotplug = 1, + .has_overlay = 1, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_ironlake_d_info = { + .gen = 5, .num_pipes = 2, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_ironlake_m_info = { + .gen = 5, .is_mobile = 1, .num_pipes = 2, + .need_gfx_hws = 1, .has_hotplug = 1, + .has_fbc = 1, + .ring_mask = RENDER_RING | BSD_RING, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_sandybridge_d_info = { + .gen = 6, .num_pipes = 2, + .need_gfx_hws = 1, .has_hotplug = 1, + .has_fbc = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING, + .has_llc = 1, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +static const struct intel_device_info intel_sandybridge_m_info = { + .gen = 6, .is_mobile = 1, .num_pipes = 2, + .need_gfx_hws = 1, .has_hotplug = 1, + .has_fbc = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING, + .has_llc = 1, + GEN_DEFAULT_PIPEOFFSETS, + CURSOR_OFFSETS, +}; + +#define GEN7_FEATURES \ + .gen = 7, .num_pipes = 3, \ + .need_gfx_hws = 1, .has_hotplug = 1, \ + .has_fbc = 1, \ + .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ + .has_llc = 1, \ + GEN_DEFAULT_PIPEOFFSETS, \ + IVB_CURSOR_OFFSETS + +static const struct intel_device_info intel_ivybridge_d_info = { + GEN7_FEATURES, + .is_ivybridge = 1, +}; + +static const struct intel_device_info intel_ivybridge_m_info = { + GEN7_FEATURES, + .is_ivybridge = 1, + .is_mobile = 1, +}; + +static const struct intel_device_info intel_ivybridge_q_info = { + GEN7_FEATURES, + .is_ivybridge = 1, + .num_pipes = 0, /* legal, last one wins */ +}; + +#define VLV_FEATURES \ + .gen = 7, .num_pipes = 2, \ + .need_gfx_hws = 1, .has_hotplug = 1, \ + .ring_mask = RENDER_RING | BSD_RING | BLT_RING, \ + .display_mmio_offset = VLV_DISPLAY_BASE, \ + GEN_DEFAULT_PIPEOFFSETS, \ + CURSOR_OFFSETS + +static const struct intel_device_info intel_valleyview_m_info = { + VLV_FEATURES, + .is_valleyview = 1, + .is_mobile = 1, +}; + +static const struct intel_device_info intel_valleyview_d_info = { + VLV_FEATURES, + .is_valleyview = 1, +}; + +#define HSW_FEATURES \ + GEN7_FEATURES, \ + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, \ + .has_ddi = 1, \ + .has_fpga_dbg = 1 + +static const struct intel_device_info intel_haswell_d_info = { + HSW_FEATURES, + .is_haswell = 1, +}; + +static const struct intel_device_info intel_haswell_m_info = { + HSW_FEATURES, + .is_haswell = 1, + .is_mobile = 1, +}; + +#define BDW_FEATURES \ + HSW_FEATURES, \ + BDW_COLORS + +static const struct intel_device_info intel_broadwell_d_info = { + BDW_FEATURES, + .gen = 8, + .is_broadwell = 1, +}; + +static const struct intel_device_info intel_broadwell_m_info = { + BDW_FEATURES, + .gen = 8, .is_mobile = 1, + .is_broadwell = 1, +}; + +static const struct intel_device_info intel_broadwell_gt3d_info = { + BDW_FEATURES, + .gen = 8, + .is_broadwell = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, +}; + +static const struct intel_device_info intel_broadwell_gt3m_info = { + BDW_FEATURES, + .gen = 8, .is_mobile = 1, + .is_broadwell = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, +}; + +static const struct intel_device_info intel_cherryview_info = { + .gen = 8, .num_pipes = 3, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, + .is_cherryview = 1, + .display_mmio_offset = VLV_DISPLAY_BASE, + GEN_CHV_PIPEOFFSETS, + CURSOR_OFFSETS, + CHV_COLORS, +}; + +static const struct intel_device_info intel_skylake_info = { + BDW_FEATURES, + .is_skylake = 1, + .gen = 9, +}; + +static const struct intel_device_info intel_skylake_gt3_info = { + BDW_FEATURES, + .is_skylake = 1, + .gen = 9, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, +}; + +static const struct intel_device_info intel_broxton_info = { + .is_preliminary = 1, + .is_broxton = 1, + .gen = 9, + .need_gfx_hws = 1, .has_hotplug = 1, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING, + .num_pipes = 3, + .has_ddi = 1, + .has_fpga_dbg = 1, + .has_fbc = 1, + .has_pooled_eu = 0, + GEN_DEFAULT_PIPEOFFSETS, + IVB_CURSOR_OFFSETS, + BDW_COLORS, +}; + +static const struct intel_device_info intel_kabylake_info = { + BDW_FEATURES, + .is_kabylake = 1, + .gen = 9, +}; + +static const struct intel_device_info intel_kabylake_gt3_info = { + BDW_FEATURES, + .is_kabylake = 1, + .gen = 9, + .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING, +}; + +/* + * Make sure any device matches here are from most specific to most + * general. For example, since the Quanta match is based on the subsystem + * and subvendor IDs, we need it to come before the more general IVB + * PCI ID matches, otherwise we'll use the wrong info struct above. + */ +static const struct pci_device_id pciidlist[] = { + INTEL_I830_IDS(&intel_i830_info), + INTEL_I845G_IDS(&intel_845g_info), + INTEL_I85X_IDS(&intel_i85x_info), + INTEL_I865G_IDS(&intel_i865g_info), + INTEL_I915G_IDS(&intel_i915g_info), + INTEL_I915GM_IDS(&intel_i915gm_info), + INTEL_I945G_IDS(&intel_i945g_info), + INTEL_I945GM_IDS(&intel_i945gm_info), + INTEL_I965G_IDS(&intel_i965g_info), + INTEL_G33_IDS(&intel_g33_info), + INTEL_I965GM_IDS(&intel_i965gm_info), + INTEL_GM45_IDS(&intel_gm45_info), + INTEL_G45_IDS(&intel_g45_info), + INTEL_PINEVIEW_IDS(&intel_pineview_info), + INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info), + INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info), + INTEL_SNB_D_IDS(&intel_sandybridge_d_info), + INTEL_SNB_M_IDS(&intel_sandybridge_m_info), + INTEL_IVB_Q_IDS(&intel_ivybridge_q_info), /* must be first IVB */ + INTEL_IVB_M_IDS(&intel_ivybridge_m_info), + INTEL_IVB_D_IDS(&intel_ivybridge_d_info), + INTEL_HSW_D_IDS(&intel_haswell_d_info), + INTEL_HSW_M_IDS(&intel_haswell_m_info), + INTEL_VLV_M_IDS(&intel_valleyview_m_info), + INTEL_VLV_D_IDS(&intel_valleyview_d_info), + INTEL_BDW_GT12M_IDS(&intel_broadwell_m_info), + INTEL_BDW_GT12D_IDS(&intel_broadwell_d_info), + INTEL_BDW_GT3M_IDS(&intel_broadwell_gt3m_info), + INTEL_BDW_GT3D_IDS(&intel_broadwell_gt3d_info), + INTEL_CHV_IDS(&intel_cherryview_info), + INTEL_SKL_GT1_IDS(&intel_skylake_info), + INTEL_SKL_GT2_IDS(&intel_skylake_info), + INTEL_SKL_GT3_IDS(&intel_skylake_gt3_info), + INTEL_SKL_GT4_IDS(&intel_skylake_gt3_info), + INTEL_BXT_IDS(&intel_broxton_info), + INTEL_KBL_GT1_IDS(&intel_kabylake_info), + INTEL_KBL_GT2_IDS(&intel_kabylake_info), + INTEL_KBL_GT3_IDS(&intel_kabylake_gt3_info), + INTEL_KBL_GT4_IDS(&intel_kabylake_gt3_info), + {0, 0, 0} +}; +MODULE_DEVICE_TABLE(pci, pciidlist); + +extern int i915_driver_load(struct pci_dev *pdev, + const struct pci_device_id *ent); + +static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct intel_device_info *intel_info = + (struct intel_device_info *) ent->driver_data; + + if (IS_PRELIMINARY_HW(intel_info) && !i915.preliminary_hw_support) { + DRM_INFO("This hardware requires preliminary hardware support.\n" + "See CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT, and/or modparam preliminary_hw_support\n"); + return -ENODEV; + } + + /* Only bind to function 0 of the device. Early generations + * used function 1 as a placeholder for multi-head. This causes + * us confusion instead, especially on the systems where both + * functions have the same PCI-ID! + */ + if (PCI_FUNC(pdev->devfn)) + return -ENODEV; + + /* + * apple-gmux is needed on dual GPU MacBook Pro + * to probe the panel if we're the inactive GPU. + */ + if (vga_switcheroo_client_probe_defer(pdev)) + return -EPROBE_DEFER; + + return i915_driver_load(pdev, ent); +} + +extern void i915_driver_unload(struct drm_device *dev); + +static void i915_pci_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + i915_driver_unload(dev); + drm_dev_unref(dev); +} + +extern const struct dev_pm_ops i915_pm_ops; + +struct pci_driver i915_pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + .probe = i915_pci_probe, + .remove = i915_pci_remove, + .driver.pm = &i915_pm_ops, +}; -- cgit v1.2.3 From a09d0ba1745b607070a937083ecf9ec616178768 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:00:27 +0100 Subject: drm/i915: Move module init/exit to i915_pci.c The module init/exit routines are a wrapper around the PCI device init/exit, so move them across. Note that in order to avoid exporting the driver struct, instead of manipulating driver.features inside i915_init we instead opt to simply exit if i915.modeset is disabled. Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Joonas Lahtinen Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466773227-7994-15-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 51 +++-------------------------------------- drivers/gpu/drm/i915/i915_pci.c | 45 +++++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7d011a686bc9..b98afbd33235 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -28,7 +28,6 @@ */ #include -#include #include #include #include @@ -1592,6 +1591,9 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) struct drm_i915_private *dev_priv; int ret; + if (i915.nuclear_pageflip) + driver.driver_features |= DRIVER_ATOMIC; + ret = -ENOMEM; dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (dev_priv) @@ -3018,50 +3020,3 @@ static struct drm_driver driver = { .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, }; - -static int __init i915_init(void) -{ - extern struct pci_driver i915_pci_driver; - - /* - * Enable KMS by default, unless explicitly overriden by - * either the i915.modeset prarameter or by the - * vga_text_mode_force boot option. - */ - - if (i915.modeset == 0) - driver.driver_features &= ~DRIVER_MODESET; - - if (vgacon_text_force() && i915.modeset == -1) - driver.driver_features &= ~DRIVER_MODESET; - - if (!(driver.driver_features & DRIVER_MODESET)) { - /* Silently fail loading to not upset userspace. */ - DRM_DEBUG_DRIVER("KMS disabled.\n"); - return 0; - } - - if (i915.nuclear_pageflip) - driver.driver_features |= DRIVER_ATOMIC; - - return drm_pci_init(&driver, &i915_pci_driver); -} - -static void __exit i915_exit(void) -{ - extern struct pci_driver i915_pci_driver; - - if (!(driver.driver_features & DRIVER_MODESET)) - return; /* Never loaded a driver. */ - - drm_pci_exit(&driver, &i915_pci_driver); -} - -module_init(i915_init); -module_exit(i915_exit); - -MODULE_AUTHOR("Tungsten Graphics, Inc."); -MODULE_AUTHOR("Intel Corporation"); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 9aa07f38caea..a7f8f4fb7e8d 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -22,6 +22,7 @@ * */ +#include #include #include @@ -452,10 +453,52 @@ static void i915_pci_remove(struct pci_dev *pdev) extern const struct dev_pm_ops i915_pm_ops; -struct pci_driver i915_pci_driver = { +static struct pci_driver i915_pci_driver = { .name = DRIVER_NAME, .id_table = pciidlist, .probe = i915_pci_probe, .remove = i915_pci_remove, .driver.pm = &i915_pm_ops, }; + +static int __init i915_init(void) +{ + bool use_kms = true; + + /* + * Enable KMS by default, unless explicitly overriden by + * either the i915.modeset prarameter or by the + * vga_text_mode_force boot option. + */ + + if (i915.modeset == 0) + use_kms = false; + + if (vgacon_text_force() && i915.modeset == -1) + use_kms = false; + + if (!use_kms) { + /* Silently fail loading to not upset userspace. */ + DRM_DEBUG_DRIVER("KMS disabled.\n"); + return 0; + } + + return pci_register_driver(&i915_pci_driver); +} + +static void __exit i915_exit(void) +{ + if (!i915_pci_driver.driver.owner) + return; + + pci_unregister_driver(&i915_pci_driver); +} + +module_init(i915_init); +module_exit(i915_exit); + +MODULE_AUTHOR("Tungsten Graphics, Inc."); +MODULE_AUTHOR("Intel Corporation"); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL and additional rights"); -- cgit v1.2.3 From 62e6300768f6550ba24fa3ba2d4c66d725e3c890 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:55:52 +0100 Subject: drm/i915: Skip idling an idle engine During suspend (or module unload), if we have never accessed the engine (i.e. userspace never submitted a batch to it), the engine is idle. Then we attempt to idle the engine by forcing it to the default context, which actually means we submit a render batch to setup the golden context state and then wait for it to complete. We can skip this entirely as we know the engine is idle. v2: Drop incorrect comment. References: https://bugs.freedesktop.org/show_bug.cgi?id=95634 Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466776558-21516-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6abd5e590373..a0533ca089c5 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3677,8 +3677,10 @@ int i915_gpu_idle(struct drm_device *dev) struct intel_engine_cs *engine; int ret; - /* Flush everything onto the inactive list. */ for_each_engine(engine, dev_priv) { + if (engine->last_context == NULL) + continue; + if (!i915.enable_execlists) { struct drm_i915_gem_request *req; -- cgit v1.2.3 From 0cb26a8ed1a61a31a79bb9fd97687fb0a76ce221 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:55:53 +0100 Subject: drm/i915: Move legacy kernel context pinning to intel_ringbuffer.c This is so that we have symmetry with intel_lrc.c and avoid a source of if (i915.enable_execlists) layering violation within i915_gem_context.c - that is we move the specific handling of the dev_priv->kernel_context for legacy submission into the legacy submission code. This depends upon the init/fini ordering between contexts and engines already defined by intel_lrc.c, and also exporting the context alignment required for pinning the legacy context. v2: Separate out pin/unpin context funcs for greater symmetry with intel_lrc. One more step towards unifying behaviour between the two classes of engines and towards fixing another bug in i915_switch_context vs requests. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466776558-21516-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem_context.c | 27 ++-------------- drivers/gpu/drm/i915/intel_ringbuffer.c | 55 +++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5b68c07b3921..2b01bbc1fb6e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -872,6 +872,8 @@ struct i915_gem_context { u32 user_handle; #define CONTEXT_NO_ZEROMAP (1<<0) + u32 ggtt_alignment; + struct intel_context { struct drm_i915_gem_object *state; struct intel_ringbuffer *ringbuf; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 30d9b4fd30f3..419d2551dc6b 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -268,6 +268,8 @@ __create_hw_context(struct drm_device *dev, list_add_tail(&ctx->link, &dev_priv->context_list); ctx->i915 = dev_priv; + ctx->ggtt_alignment = get_context_alignment(dev_priv); + if (dev_priv->hw_context_size) { struct drm_i915_gem_object *obj = i915_gem_alloc_context_obj(dev, dev_priv->hw_context_size); @@ -451,26 +453,6 @@ int i915_gem_context_init(struct drm_device *dev) return PTR_ERR(ctx); } - if (!i915.enable_execlists && ctx->engine[RCS].state) { - int ret; - - /* We may need to do things with the shrinker which - * require us to immediately switch back to the default - * context. This can cause a problem as pinning the - * default context also requires GTT space which may not - * be available. To avoid this we always pin the default - * context. - */ - ret = i915_gem_obj_ggtt_pin(ctx->engine[RCS].state, - get_context_alignment(dev_priv), 0); - if (ret) { - DRM_ERROR("Failed to pinned default global context (error %d)\n", - ret); - i915_gem_context_unreference(ctx); - return ret; - } - } - dev_priv->kernel_context = ctx; DRM_DEBUG_DRIVER("%s context support initialized\n", @@ -507,9 +489,6 @@ void i915_gem_context_fini(struct drm_device *dev) lockdep_assert_held(&dev->struct_mutex); - if (!i915.enable_execlists && dctx->engine[RCS].state) - i915_gem_object_ggtt_unpin(dctx->engine[RCS].state); - i915_gem_context_unreference(dctx); dev_priv->kernel_context = NULL; @@ -759,7 +738,7 @@ static int do_rcs_switch(struct drm_i915_gem_request *req) /* Trying to pin first makes error handling easier. */ ret = i915_gem_obj_ggtt_pin(to->engine[RCS].state, - get_context_alignment(engine->i915), + to->ggtt_alignment, 0); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index fedd27049814..86b80b4727fb 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2321,6 +2321,47 @@ intel_ringbuffer_free(struct intel_ringbuffer *ring) kfree(ring); } +static int intel_ring_context_pin(struct i915_gem_context *ctx, + struct intel_engine_cs *engine) +{ + struct intel_context *ce = &ctx->engine[engine->id]; + int ret; + + lockdep_assert_held(&ctx->i915->dev->struct_mutex); + + if (ce->pin_count++) + return 0; + + if (ce->state) { + ret = i915_gem_obj_ggtt_pin(ce->state, ctx->ggtt_alignment, 0); + if (ret) + goto error; + } + + i915_gem_context_reference(ctx); + return 0; + +error: + ce->pin_count = 0; + return ret; +} + +static void intel_ring_context_unpin(struct i915_gem_context *ctx, + struct intel_engine_cs *engine) +{ + struct intel_context *ce = &ctx->engine[engine->id]; + + lockdep_assert_held(&ctx->i915->dev->struct_mutex); + + if (--ce->pin_count) + return; + + if (ce->state) + i915_gem_object_ggtt_unpin(ce->state); + + i915_gem_context_unreference(ctx); +} + static int intel_init_ring_buffer(struct drm_device *dev, struct intel_engine_cs *engine) { @@ -2341,6 +2382,17 @@ static int intel_init_ring_buffer(struct drm_device *dev, init_waitqueue_head(&engine->irq_queue); + /* We may need to do things with the shrinker which + * require us to immediately switch back to the default + * context. This can cause a problem as pinning the + * default context also requires GTT space which may not + * be available. To avoid this we always pin the default + * context. + */ + ret = intel_ring_context_pin(dev_priv->kernel_context, engine); + if (ret) + goto error; + ringbuf = intel_engine_create_ringbuffer(engine, 32 * PAGE_SIZE); if (IS_ERR(ringbuf)) { ret = PTR_ERR(ringbuf); @@ -2408,6 +2460,9 @@ void intel_cleanup_engine(struct intel_engine_cs *engine) i915_cmd_parser_fini_ring(engine); i915_gem_batch_pool_fini(&engine->batch_pool); + + intel_ring_context_unpin(dev_priv->kernel_context, engine); + engine->i915 = NULL; } -- cgit v1.2.3 From c7c3c07d16dd51faddeb6ae665d360be030b31b0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:55:54 +0100 Subject: drm/i915: Treat kernel context as initialised The kernel context exists simply as a placeholder and should never be executed with a render context. It does not need the golden render state, as that will always be applied to a user context. By skipping the initialisation we can avoid issues in attempting to program the golden render context when trying to make the hardware idle. v2: Rebase Testcase: igt/drm_module_reload_basic #byt Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95634 Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466776558-21516-3-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_context.c | 14 +++++++++----- drivers/gpu/drm/i915/intel_ringbuffer.c | 10 ++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 419d2551dc6b..4f4fd65c558b 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -472,13 +472,17 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv) i915_gem_context_unpin(engine->last_context, engine); engine->last_context = NULL; } - - /* Force the GPU state to be reinitialised on enabling */ - dev_priv->kernel_context->engine[engine->id].initialised = - engine->init_context == NULL; } - /* Force the GPU state to be reinitialised on enabling */ + /* Force the GPU state to be restored on enabling */ + if (!i915.enable_execlists) { + for_each_engine(engine, dev_priv) { + struct intel_context *kce = + &dev_priv->kernel_context->engine[engine->id]; + + kce->initialised = true; + } + } dev_priv->kernel_context->remap_slice = ALL_L3_SLICES(dev_priv); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 86b80b4727fb..04a2d141e690 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2338,6 +2338,16 @@ static int intel_ring_context_pin(struct i915_gem_context *ctx, goto error; } + /* The kernel context is only used as a placeholder for flushing the + * active context. It is never used for submitting user rendering and + * as such never requires the golden render context, and so we can skip + * emitting it when we switch to the kernel context. This is required + * as during eviction we cannot allocate and pin the renderstate in + * order to initialise the context. + */ + if (ctx == ctx->i915->kernel_context) + ce->initialised = true; + i915_gem_context_reference(ctx); return 0; -- cgit v1.2.3 From a168b2d8a5195f1744205b2ad7d412eb29bd3f1f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:55:55 +0100 Subject: drm/i915: Mark all default contexts as uninitialised after context loss When the GPU is reset or state lost through suspend, every default legacy context needs to reload their state - both the golden render state and the L3 mapping. Only context images explicitly saved to memory (i.e. all execlists and non-default legacy contexts) will retain their state across the reset. v2: Rebase Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466776558-21516-4-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_context.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 4f4fd65c558b..3a6594b70900 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -476,6 +476,18 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv) /* Force the GPU state to be restored on enabling */ if (!i915.enable_execlists) { + struct i915_gem_context *ctx; + + list_for_each_entry(ctx, &dev_priv->context_list, link) { + if (!i915_gem_context_is_default(ctx)) + continue; + + for_each_engine(engine, dev_priv) + ctx->engine[engine->id].initialised = false; + + ctx->remap_slice = ALL_L3_SLICES(dev_priv); + } + for_each_engine(engine, dev_priv) { struct intel_context *kce = &dev_priv->kernel_context->engine[engine->id]; @@ -483,7 +495,6 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv) kce->initialised = true; } } - dev_priv->kernel_context->remap_slice = ALL_L3_SLICES(dev_priv); } void i915_gem_context_fini(struct drm_device *dev) -- cgit v1.2.3 From ec602a0dfb394ac3a5f91d03c4d6fab6e45302cc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:55:56 +0100 Subject: drm/i915: No need to wait for idle on L3 remap As the L3 remapping is applied before the next execution, there is no need to wait until all previous uses are idle, the application will not occur any sooner. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Reviewed-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1466776558-21516-5-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_sysfs.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 02507bfc8def..a6e90fe05a1e 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -227,13 +227,6 @@ i915_l3_write(struct file *filp, struct kobject *kobj, } } - ret = i915_gpu_idle(drm_dev); - if (ret) { - kfree(temp); - mutex_unlock(&drm_dev->struct_mutex); - return ret; - } - /* TODO: Ideally we really want a GPU reset here to make sure errors * aren't propagated. Since I cannot find a stable way to reset the GPU * at this point it is left as a TODO. -- cgit v1.2.3 From 6e5a5beb8e344b1ab929de0c8446a61a70ed94ba Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:55:57 +0100 Subject: drm/i915: Split idling from forcing context switch We only need to force a switch to the kernel context placeholder during eviction. All other uses of i915_gpu_idle() just want to wait until existing work on the GPU is idle. Rename i915_gpu_idle() to i915_gem_wait_for_idle() to avoid any implications about "parking" the context first. v2: Tweak an error message if the wait fails for the ilk vtd w/a Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1466776558-21516-6-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 20 +++---------- drivers/gpu/drm/i915/i915_gem_evict.c | 51 +++++++++++++++++++++++++++++--- drivers/gpu/drm/i915/i915_gem_gtt.c | 4 +-- drivers/gpu/drm/i915/i915_gem_shrinker.c | 2 +- 6 files changed, 56 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a8e0eb7e146c..f664884ad27f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4947,7 +4947,7 @@ i915_drop_caches_set(void *data, u64 val) return ret; if (val & DROP_ACTIVE) { - ret = i915_gpu_idle(dev); + ret = i915_gem_wait_for_idle(dev_priv); if (ret) goto unlock; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2b01bbc1fb6e..9ef491975812 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3336,7 +3336,7 @@ int i915_gem_init_engines(struct drm_device *dev); int __must_check i915_gem_init_hw(struct drm_device *dev); void i915_gem_init_swizzling(struct drm_device *dev); void i915_gem_cleanup_engines(struct drm_device *dev); -int __must_check i915_gpu_idle(struct drm_device *dev); +int __must_check i915_gem_wait_for_idle(struct drm_i915_private *dev_priv); int __must_check i915_gem_suspend(struct drm_device *dev); void __i915_add_request(struct drm_i915_gem_request *req, struct drm_i915_gem_object *batch_obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a0533ca089c5..51191b879747 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3671,29 +3671,17 @@ int __i915_vma_unbind_no_wait(struct i915_vma *vma) return __i915_vma_unbind(vma, false); } -int i915_gpu_idle(struct drm_device *dev) +int i915_gem_wait_for_idle(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine; int ret; + lockdep_assert_held(&dev_priv->dev->struct_mutex); + for_each_engine(engine, dev_priv) { if (engine->last_context == NULL) continue; - if (!i915.enable_execlists) { - struct drm_i915_gem_request *req; - - req = i915_gem_request_alloc(engine, NULL); - if (IS_ERR(req)) - return PTR_ERR(req); - - ret = i915_switch_context(req); - i915_add_request_no_flush(req); - if (ret) - return ret; - } - ret = intel_engine_idle(engine); if (ret) return ret; @@ -4963,7 +4951,7 @@ i915_gem_suspend(struct drm_device *dev) int ret = 0; mutex_lock(&dev->struct_mutex); - ret = i915_gpu_idle(dev); + ret = i915_gem_wait_for_idle(dev_priv); if (ret) goto err; diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index b144c3f5c650..5741b58d186c 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -33,6 +33,37 @@ #include "intel_drv.h" #include "i915_trace.h" +static int switch_to_pinned_context(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *engine; + + if (i915.enable_execlists) + return 0; + + for_each_engine(engine, dev_priv) { + struct drm_i915_gem_request *req; + int ret; + + if (engine->last_context == NULL) + continue; + + if (engine->last_context == dev_priv->kernel_context) + continue; + + req = i915_gem_request_alloc(engine, dev_priv->kernel_context); + if (IS_ERR(req)) + return PTR_ERR(req); + + ret = i915_switch_context(req); + i915_add_request_no_flush(req); + if (ret) + return ret; + } + + return 0; +} + + static bool mark_free(struct i915_vma *vma, struct list_head *unwind) { @@ -150,11 +181,17 @@ none: /* Only idle the GPU and repeat the search once */ if (pass++ == 0) { - ret = i915_gpu_idle(dev); + struct drm_i915_private *dev_priv = to_i915(dev); + + ret = switch_to_pinned_context(dev_priv); if (ret) return ret; - i915_gem_retire_requests(to_i915(dev)); + ret = i915_gem_wait_for_idle(dev_priv); + if (ret) + return ret; + + i915_gem_retire_requests(dev_priv); goto search_again; } @@ -261,11 +298,17 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle) trace_i915_gem_evict_vm(vm); if (do_idle) { - ret = i915_gpu_idle(vm->dev); + struct drm_i915_private *dev_priv = to_i915(vm->dev); + + ret = switch_to_pinned_context(dev_priv); + if (ret) + return ret; + + ret = i915_gem_wait_for_idle(dev_priv); if (ret) return ret; - i915_gem_retire_requests(to_i915(vm->dev)); + i915_gem_retire_requests(dev_priv); WARN_ON(!list_empty(&vm->active_list)); } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 5890017b9832..6b0697176a4f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2261,8 +2261,8 @@ static bool do_idling(struct drm_i915_private *dev_priv) if (unlikely(ggtt->do_idle_maps)) { dev_priv->mm.interruptible = false; - if (i915_gpu_idle(dev_priv->dev)) { - DRM_ERROR("Couldn't idle GPU\n"); + if (i915_gem_wait_for_idle(dev_priv)) { + DRM_ERROR("Failed to wait for idle; VT'd may hang.\n"); /* Wait a bit, in hopes it avoids the hang */ udelay(10); } diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 538c30499848..886a8797566d 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -408,7 +408,7 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr return NOTIFY_DONE; /* Force everything onto the inactive lists */ - ret = i915_gpu_idle(dev_priv->dev); + ret = i915_gem_wait_for_idle(dev_priv); if (ret) goto out; -- cgit v1.2.3 From 883445d43e45ddc5ef19274a169a1aa603428ab6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:55:58 +0100 Subject: drm/i915: Only switch to default context when evicting from GGTT The contexts only pin space within the global GTT. Therefore forcing the switch to the perma-pinned kernel context only has an effect when trying to evict from and find room within the global GTT. We can then restrict the switch to only when operating on the default context. This is mostly a no-op as full-ppgtt only exists with execlists at present which skips the context switch anyway. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466776558-21516-7-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_evict.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 5741b58d186c..3c1280ec7ff6 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -183,9 +183,11 @@ none: if (pass++ == 0) { struct drm_i915_private *dev_priv = to_i915(dev); - ret = switch_to_pinned_context(dev_priv); - if (ret) - return ret; + if (i915_is_ggtt(vm)) { + ret = switch_to_pinned_context(dev_priv); + if (ret) + return ret; + } ret = i915_gem_wait_for_idle(dev_priv); if (ret) @@ -300,9 +302,11 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle) if (do_idle) { struct drm_i915_private *dev_priv = to_i915(vm->dev); - ret = switch_to_pinned_context(dev_priv); - if (ret) - return ret; + if (i915_is_ggtt(vm)) { + ret = switch_to_pinned_context(dev_priv); + if (ret) + return ret; + } ret = i915_gem_wait_for_idle(dev_priv); if (ret) -- cgit v1.2.3 From 731f74c5c644f113186288013e73382e20dd1d9e Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Fri, 24 Jun 2016 19:37:46 +0100 Subject: drm/i915: tweak gen6_for_{each_pde, all_pdes} macros Gen8 versions of these macros were updated a few months ago (e8ebd8e drm/i915: eliminate 'temp' in gen8_for_each macros) originally because at least one iterator could generate an out of bounds access, but also because eliminating the 'temp' parameter generated smaller and faster code. Matthew Auld recently noticed the same problem with the gen6 versions and provided a patch https://lists.freedesktop.org/archives/intel-gfx/2016-June/099334.html but while we're changing these, we might as well make them as much like the gen8 versions as possible, including the style of using "&& (..., true)" rather than ": (..., 1) : 0", and of course eliminating the redundant 'temp'. Furthermore, the "all_pdes" version is only used in one place, so we can improve code efficiency by changing both the macro parameters and the calling code to reduce extra dereferences. Signed-off-by: Dave Gordon Cc: Matthew Auld Cc: Chris Wilson Reviewed-by: Matthew Auld Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1466793466-23500-1-git-send-email-david.s.gordon@intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 25 ++++++++++++----------- drivers/gpu/drm/i915/i915_gem_gtt.h | 40 ++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6b0697176a4f..0bb18b88dc7a 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1570,13 +1570,13 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m) struct i915_page_table *unused; gen6_pte_t scratch_pte; uint32_t pd_entry; - uint32_t pte, pde, temp; + uint32_t pte, pde; uint32_t start = ppgtt->base.start, length = ppgtt->base.total; scratch_pte = vm->pte_encode(px_dma(vm->scratch_page), I915_CACHE_LLC, true, 0); - gen6_for_each_pde(unused, &ppgtt->pd, start, length, temp, pde) { + gen6_for_each_pde(unused, &ppgtt->pd, start, length, pde) { u32 expected; gen6_pte_t *pt_vaddr; const dma_addr_t pt_addr = px_dma(ppgtt->pd.page_table[pde]); @@ -1640,9 +1640,9 @@ static void gen6_write_page_range(struct drm_i915_private *dev_priv, { struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_page_table *pt; - uint32_t pde, temp; + uint32_t pde; - gen6_for_each_pde(pt, pd, start, length, temp, pde) + gen6_for_each_pde(pt, pd, start, length, pde) gen6_write_pde(pd, pde, pt); /* Make sure write is complete before other code can use this page @@ -1875,7 +1875,7 @@ static int gen6_alloc_va_range(struct i915_address_space *vm, struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm); struct i915_page_table *pt; uint32_t start, length, start_save, length_save; - uint32_t pde, temp; + uint32_t pde; int ret; if (WARN_ON(start_in + length_in > ppgtt->base.total)) @@ -1891,7 +1891,7 @@ static int gen6_alloc_va_range(struct i915_address_space *vm, * need allocation. The second stage marks use ptes within the page * tables. */ - gen6_for_each_pde(pt, &ppgtt->pd, start, length, temp, pde) { + gen6_for_each_pde(pt, &ppgtt->pd, start, length, pde) { if (pt != vm->scratch_pt) { WARN_ON(bitmap_empty(pt->used_ptes, GEN6_PTES)); continue; @@ -1916,7 +1916,7 @@ static int gen6_alloc_va_range(struct i915_address_space *vm, start = start_save; length = length_save; - gen6_for_each_pde(pt, &ppgtt->pd, start, length, temp, pde) { + gen6_for_each_pde(pt, &ppgtt->pd, start, length, pde) { DECLARE_BITMAP(tmp_bitmap, GEN6_PTES); bitmap_zero(tmp_bitmap, GEN6_PTES); @@ -1985,15 +1985,16 @@ static void gen6_free_scratch(struct i915_address_space *vm) static void gen6_ppgtt_cleanup(struct i915_address_space *vm) { struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm); + struct i915_page_directory *pd = &ppgtt->pd; + struct drm_device *dev = vm->dev; struct i915_page_table *pt; uint32_t pde; drm_mm_remove_node(&ppgtt->node); - gen6_for_all_pdes(pt, ppgtt, pde) { + gen6_for_all_pdes(pt, pd, pde) if (pt != vm->scratch_pt) - free_pt(ppgtt->base.dev, pt); - } + free_pt(dev, pt); gen6_free_scratch(vm); } @@ -2059,9 +2060,9 @@ static void gen6_scratch_va_range(struct i915_hw_ppgtt *ppgtt, uint64_t start, uint64_t length) { struct i915_page_table *unused; - uint32_t pde, temp; + uint32_t pde; - gen6_for_each_pde(unused, &ppgtt->pd, start, length, temp, pde) + gen6_for_each_pde(unused, &ppgtt->pd, start, length, pde) ppgtt->pd.page_table[pde] = ppgtt->base.scratch_pt; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 163b564fb87d..aa5f31d1c2ed 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -390,27 +390,27 @@ struct i915_hw_ppgtt { void (*debug_dump)(struct i915_hw_ppgtt *ppgtt, struct seq_file *m); }; -/* For each pde iterates over every pde between from start until start + length. - * If start, and start+length are not perfectly divisible, the macro will round - * down, and up as needed. The macro modifies pde, start, and length. Dev is - * only used to differentiate shift values. Temp is temp. On gen6/7, start = 0, - * and length = 2G effectively iterates over every PDE in the system. - * - * XXX: temp is not actually needed, but it saves doing the ALIGN operation. +/* + * gen6_for_each_pde() iterates over every pde from start until start+length. + * If start and start+length are not perfectly divisible, the macro will round + * down and up as needed. Start=0 and length=2G effectively iterates over + * every PDE in the system. The macro modifies ALL its parameters except 'pd', + * so each of the other parameters should preferably be a simple variable, or + * at most an lvalue with no side-effects! */ -#define gen6_for_each_pde(pt, pd, start, length, temp, iter) \ - for (iter = gen6_pde_index(start); \ - length > 0 && iter < I915_PDES ? \ - (pt = (pd)->page_table[iter]), 1 : 0; \ - iter++, \ - temp = ALIGN(start+1, 1 << GEN6_PDE_SHIFT) - start, \ - temp = min_t(unsigned, temp, length), \ - start += temp, length -= temp) - -#define gen6_for_all_pdes(pt, ppgtt, iter) \ - for (iter = 0; \ - pt = ppgtt->pd.page_table[iter], iter < I915_PDES; \ - iter++) +#define gen6_for_each_pde(pt, pd, start, length, iter) \ + for (iter = gen6_pde_index(start); \ + length > 0 && iter < I915_PDES && \ + (pt = (pd)->page_table[iter], true); \ + ({ u32 temp = ALIGN(start+1, 1 << GEN6_PDE_SHIFT); \ + temp = min(temp - start, length); \ + start += temp, length -= temp; }), ++iter) + +#define gen6_for_all_pdes(pt, pd, iter) \ + for (iter = 0; \ + iter < I915_PDES && \ + (pt = (pd)->page_table[iter], true); \ + ++iter) static inline uint32_t i915_pte_index(uint64_t address, uint32_t pde_shift) { -- cgit v1.2.3 From fa7545a4ae8c1a0640a294db4f8b6bab8a68dcd0 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Fri, 24 Jun 2016 15:57:57 +0100 Subject: drm/i915/guc: don't ever forward VBlank to the GuC If a context waiting for VBlank were switched out, switching in the next context and generating a CSB event in the process, then the GuC would have to put the context back in the queue, and then observe the subsequent VBlank interrupt so that it could resubmit the suspended context. However, we always set the CTX_CTRL_INHIBIT_SYN_CTX_SWITCH bit in the RING_CONTEXT_CONTROL register, so this case cannot occur. Furthermore we don't use the GuC's internal scheduler or allow it to auto-resubmit workloads. Consequently, the GuC doesn't need to see VBlanks, and by sending them to it we may be waking it up unnecessarily, which might reduce RC6 residency and increase power consumption. So this patch removes the setting of the GFC_FORWARD_VBLANK field from the code that diverts interrupts towards the GuC. (The code to direct interrupts to the host, OTOH, continues to explicitly set the field to "never send VBlanks to the GuC".) v3: Remove the line of code completely (original set the field to ALWAYS forward, v1 changed it to CONDITIONAL forwarding, v2 explicitly set it to NEVER, v3 just doesn't touch it at all, as we know it's already set to NEVER). Signed-off-by: Dave Gordon Reviewed-by: Daniel Vetter (previous version) Reviewed-by: Tvrtko Ursulin Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1466780277-23435-1-git-send-email-david.s.gordon@intel.com --- drivers/gpu/drm/i915/intel_guc_loader.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 8fe96a2d989e..4f6311a91a7e 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -87,7 +87,7 @@ static void direct_interrupts_to_host(struct drm_i915_private *dev_priv) struct intel_engine_cs *engine; int irqs; - /* tell all command streamers NOT to forward interrupts and vblank to GuC */ + /* tell all command streamers NOT to forward interrupts or vblank to GuC */ irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_NEVER); irqs |= _MASKED_BIT_DISABLE(GFX_INTERRUPT_STEERING); for_each_engine(engine, dev_priv) @@ -105,9 +105,8 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) int irqs; u32 tmp; - /* tell all command streamers to forward interrupts and vblank to GuC */ - irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS); - irqs |= _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); + /* tell all command streamers to forward interrupts (but not vblank) to GuC */ + irqs = _MASKED_BIT_ENABLE(GFX_INTERRUPT_STEERING); for_each_engine(engine, dev_priv) I915_WRITE(RING_MODE_GEN7(engine), irqs); -- cgit v1.2.3 From 4aa7fb9c3c4fa04eca4e6e6020aaca7b34170381 Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Mon, 16 May 2016 11:30:57 +0200 Subject: drm/i915/dmc: Step away from symbolic links Load specific firmware versions for the DMC instead of using symbolic links. The currently recommended versions are: SKL 1.26, KBL 1.01 and BXT 1.07. Certain DMC versions need workarounds in the driver which forces us to have a tight dependency between firmware and driver. In order to be able to provide a tested and known working configuration we must lock down on a specific DMC firmware version. Cc: Rodrigo Vivi Cc: Imre Deak Cc: Mika Kuoppala Signed-off-by: Patrik Jakobsson Acked-by: Jani Nikula Reviewed-by: Mika Kuoppala Acked-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: http://patchwork.freedesktop.org/patch/msgid/1463391057-32350-1-git-send-email-patrik.jakobsson@linux.intel.com --- drivers/gpu/drm/i915/intel_csr.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 2b3b428d9cd2..ea047cd46b71 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -41,15 +41,15 @@ * be moved to FW_FAILED. */ -#define I915_CSR_KBL "i915/kbl_dmc_ver1.bin" +#define I915_CSR_KBL "i915/kbl_dmc_ver1_01.bin" MODULE_FIRMWARE(I915_CSR_KBL); #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 1) -#define I915_CSR_SKL "i915/skl_dmc_ver1.bin" +#define I915_CSR_SKL "i915/skl_dmc_ver1_26.bin" MODULE_FIRMWARE(I915_CSR_SKL); -#define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 23) +#define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 26) -#define I915_CSR_BXT "i915/bxt_dmc_ver1.bin" +#define I915_CSR_BXT "i915/bxt_dmc_ver1_07.bin" MODULE_FIRMWARE(I915_CSR_BXT); #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) @@ -286,7 +286,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; uint32_t i; uint32_t *dmc_payload; - uint32_t required_min_version; + uint32_t required_version; if (!fw) return NULL; @@ -303,24 +303,23 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, csr->version = css_header->version; if (IS_KABYLAKE(dev_priv)) { - required_min_version = KBL_CSR_VERSION_REQUIRED; + required_version = KBL_CSR_VERSION_REQUIRED; } else if (IS_SKYLAKE(dev_priv)) { - required_min_version = SKL_CSR_VERSION_REQUIRED; + required_version = SKL_CSR_VERSION_REQUIRED; } else if (IS_BROXTON(dev_priv)) { - required_min_version = BXT_CSR_VERSION_REQUIRED; + required_version = BXT_CSR_VERSION_REQUIRED; } else { MISSING_CASE(INTEL_REVID(dev_priv)); - required_min_version = 0; + required_version = 0; } - if (csr->version < required_min_version) { - DRM_INFO("Refusing to load old DMC firmware v%u.%u," - " please upgrade to v%u.%u or later" - " [" FIRMWARE_URL "].\n", + if (csr->version != required_version) { + DRM_INFO("Refusing to load DMC firmware v%u.%u," + " please use v%u.%u [" FIRMWARE_URL "].\n", CSR_VERSION_MAJOR(csr->version), CSR_VERSION_MINOR(csr->version), - CSR_VERSION_MAJOR(required_min_version), - CSR_VERSION_MINOR(required_min_version)); + CSR_VERSION_MAJOR(required_version), + CSR_VERSION_MINOR(required_version)); return NULL; } -- cgit v1.2.3 From bdaa2dfbba3e07e171bccd2404fa3f75dbc66972 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 27 Jun 2016 14:53:19 +0300 Subject: drm/i915: fix build errors when ACPI is not enabled Fix build errors when ACPI is not enabled by adding function stubs: ../drivers/gpu/drm/i915/i915_drv.c: In function 'i915_drm_suspend': ../drivers/gpu/drm/i915/i915_drv.c:635:2: error: implicit declaration of function 'intel_opregion_unregister' [-Werror=implicit-function-declaration] intel_opregion_unregister(dev_priv); ../drivers/gpu/drm/i915/i915_drv.c: In function 'i915_drm_resume': ../drivers/gpu/drm/i915/i915_drv.c:798:2: error: implicit declaration of function 'intel_opregion_register' [-Werror=implicit-function-declaration] intel_opregion_register(dev_priv); Signed-off-by: Randy Dunlap Cc: Daniel Vetter Cc: Jani Nikula Cc: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Fixes: 03d92e4779b8 ("drm/i915/opregion: Rename init/fini functions to register/unregister") Cc: drm-intel-fixes@lists.freedesktop.org Cc: Chris Wilson Reviewed-by: Chris Wilson [Jani: dropped the stale init/fini declarations] Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/1467028399-9965-1-git-send-email-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9ef491975812..724d34b00196 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3694,8 +3694,8 @@ extern int intel_opregion_notify_adapter(struct drm_i915_private *dev_priv, extern int intel_opregion_get_panel_type(struct drm_i915_private *dev_priv); #else static inline int intel_opregion_setup(struct drm_i915_private *dev) { return 0; } -static inline void intel_opregion_init(struct drm_i915_private *dev) { } -static inline void intel_opregion_fini(struct drm_i915_private *dev) { } +static inline void intel_opregion_register(struct drm_i915_private *dev_priv) { } +static inline void intel_opregion_unregister(struct drm_i915_private *dev_priv) { } static inline void intel_opregion_asle_intr(struct drm_i915_private *dev_priv) { } -- cgit v1.2.3 From 9b6130227495fdaf17f8b3b28db083666b113c84 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Mon, 27 Jun 2016 16:42:44 -0700 Subject: drm/i915/gen9: Re-allocate DDB only for changed pipes When a display update triggers a DDB re-allocation, we should start by assuming that only the updated pipes need to be re-allocated (we have logic later that may add additional pipes if, e.g., a modeset triggers a change to the global allocation). We were erroneously using the _active_ pipes as our starting point rather than the changed pipes. This causes us to grab CRTC locks that we didn't actually need, reducing parallelism. Given the recent non-blocking atomic changes, it also causes legacy pageflips against one CRTC to return -EBUSY if there's an outstanding pageflip against a different CRTC (a situation easily triggered via compositors like Weston). Fixes: 98d39494d3 ("drm/i915/gen9: Compute DDB allocation at atomic check time (v4)") Cc: Maarten Lankhorst Signed-off-by: Matt Roper Link: http://patchwork.freedesktop.org/patch/msgid/1467070964-14864-1-git-send-email-matthew.d.roper@intel.com Reviewed-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_pm.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c94521cc476c..d7f8ba89d2a5 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3879,6 +3879,19 @@ static int skl_update_pipe_wm(struct drm_crtc_state *cstate, return 0; } +static uint32_t +pipes_modified(struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *cstate; + uint32_t i, ret = 0; + + for_each_crtc_in_state(state, crtc, cstate, i) + ret |= drm_crtc_mask(crtc); + + return ret; +} + static int skl_compute_ddb(struct drm_atomic_state *state) { @@ -3887,7 +3900,7 @@ skl_compute_ddb(struct drm_atomic_state *state) struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct intel_crtc *intel_crtc; struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb; - unsigned realloc_pipes = dev_priv->active_crtcs; + uint32_t realloc_pipes = pipes_modified(state); int ret; /* -- cgit v1.2.3 From 0b786e41c73956126f6297764459021deef8aba7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 28 Jun 2016 13:37:30 +0300 Subject: drm/i915/bxt: Avoid early timeout during PLL enable Since wait_for_atomic doesn't re-check the wait-for condition after expiry of the timeout it can fail when called from non-atomic context even if the condition is set correctly before the expiry. Fix this by using the non-atomic wait_for instead. I noticed this via the PLL locking timing out incorrectly, with this fix I couldn't reproduce the problem. Fixes: 0351b93992aa ("drm/i915: Do not lie about atomic timeout granularity") CC: Chris Wilson CC: Tvrtko Ursulin Signed-off-by: Imre Deak Reviewed-by: Tvrtko Ursulin CC: drm-intel-fixes@lists.freedesktop.org Link: http://patchwork.freedesktop.org/patch/msgid/1467110253-16046-2-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dpll_mgr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index c0eff1571731..e130c3ed2b6e 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -1374,8 +1374,8 @@ static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv, I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp); POSTING_READ(BXT_PORT_PLL_ENABLE(port)); - if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) & - PORT_PLL_LOCK), 200)) + if (wait_for_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) & PORT_PLL_LOCK), + 200)) DRM_ERROR("PLL %d not locked\n", port); /* -- cgit v1.2.3 From cf3598c23cd09d5f063fa8c12fe9ddd5a352d3d5 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 28 Jun 2016 13:37:31 +0300 Subject: drm/i915/lpt: Avoid early timeout during FDI PHY reset Since wait_for_atomic doesn't re-check the wait-for condition after expiry of the timeout it can fail when called from non-atomic context even if the condition is set correctly before the expiry. Fix this by using the non-atomic wait_for instead. Fixes: 0351b93992aa ("drm/i915: Do not lie about atomic timeout granularity") CC: Chris Wilson CC: Tvrtko Ursulin Signed-off-by: Imre Deak Reviewed-by: Tvrtko Ursulin CC: drm-intel-fixes@lists.freedesktop.org Link: http://patchwork.freedesktop.org/patch/msgid/1467110253-16046-3-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c3b5dc8f5e80..0312472711cc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8537,16 +8537,16 @@ static void lpt_reset_fdi_mphy(struct drm_i915_private *dev_priv) tmp |= FDI_MPHY_IOSFSB_RESET_CTL; I915_WRITE(SOUTH_CHICKEN2, tmp); - if (wait_for_atomic_us(I915_READ(SOUTH_CHICKEN2) & - FDI_MPHY_IOSFSB_RESET_STATUS, 100)) + if (wait_for_us(I915_READ(SOUTH_CHICKEN2) & + FDI_MPHY_IOSFSB_RESET_STATUS, 100)) DRM_ERROR("FDI mPHY reset assert timeout\n"); tmp = I915_READ(SOUTH_CHICKEN2); tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL; I915_WRITE(SOUTH_CHICKEN2, tmp); - if (wait_for_atomic_us((I915_READ(SOUTH_CHICKEN2) & - FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) + if (wait_for_us((I915_READ(SOUTH_CHICKEN2) & + FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) DRM_ERROR("FDI mPHY reset de-assert timeout\n"); } -- cgit v1.2.3 From f53dd63f1119a98a16d1a5a7cb3277a2f1ff483d Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 28 Jun 2016 13:37:32 +0300 Subject: drm/i915/hsw: Avoid early timeout during LCPLL disable/restore Since wait_for_atomic doesn't re-check the wait-for condition after expiry of the timeout it can fail when called from non-atomic context even if the condition is set correctly before the expiry. Fix this by using the non-atomic wait_for instead. Fixes: 0351b93992aa ("drm/i915: Do not lie about atomic timeout granularity") CC: Chris Wilson CC: Tvrtko Ursulin Signed-off-by: Imre Deak Reviewed-by: Tvrtko Ursulin CC: drm-intel-fixes@lists.freedesktop.org Link: http://patchwork.freedesktop.org/patch/msgid/1467110253-16046-4-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_display.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0312472711cc..d902a70edb84 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9534,8 +9534,8 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv, val |= LCPLL_CD_SOURCE_FCLK; I915_WRITE(LCPLL_CTL, val); - if (wait_for_atomic_us(I915_READ(LCPLL_CTL) & - LCPLL_CD_SOURCE_FCLK_DONE, 1)) + if (wait_for_us(I915_READ(LCPLL_CTL) & + LCPLL_CD_SOURCE_FCLK_DONE, 1)) DRM_ERROR("Switching to FCLK failed\n"); val = I915_READ(LCPLL_CTL); @@ -9608,8 +9608,8 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) val &= ~LCPLL_CD_SOURCE_FCLK; I915_WRITE(LCPLL_CTL, val); - if (wait_for_atomic_us((I915_READ(LCPLL_CTL) & - LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) + if (wait_for_us((I915_READ(LCPLL_CTL) & + LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1)) DRM_ERROR("Switching back to LCPLL failed\n"); } -- cgit v1.2.3 From 713a6b668932213247b394559bc229cd0fec2777 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 28 Jun 2016 13:37:33 +0300 Subject: drm/i915: Avoid early timeout during AUX transfers Since wait_for_atomic doesn't re-check the wait-for condition after expiry of the timeout it can fail when called from non-atomic context even if the condition is set correctly before the expiry. Fix this by using the non-atomic wait_for instead. Due to the relatively long 10ms timeout, probably this didn't cause any real problems, but fix it in any case for consistency. Fixes: 0351b93992aa ("drm/i915: Do not lie about atomic timeout granularity") CC: Chris Wilson CC: Tvrtko Ursulin Signed-off-by: Imre Deak Reviewed-by: Tvrtko Ursulin CC: drm-intel-fixes@lists.freedesktop.org Link: http://patchwork.freedesktop.org/patch/msgid/1467110253-16046-5-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c3742a04f611..6d586b72da88 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -727,7 +727,7 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, msecs_to_jiffies_timeout(10)); else - done = wait_for_atomic(C, 10) == 0; + done = wait_for(C, 10) == 0; if (!done) DRM_ERROR("dp aux hw did not signal timeout (has irq: %i)!\n", has_aux_irq); -- cgit v1.2.3 From 33d9391d3020e069dca98fa87a604c037beb2b9e Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 23 Jun 2016 14:50:35 -0700 Subject: drm/i915: Add more Kabylake PCI IDs. The spec has been updated adding new PCI IDs. Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: http://patchwork.freedesktop.org/patch/msgid/1466718636-19675-1-git-send-email-rodrigo.vivi@intel.com --- include/drm/i915_pciids.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 9094599a1150..87dde1c48fbf 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -309,6 +309,7 @@ INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \ INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \ INTEL_VGA_DEVICE(0x5902, info), /* DT GT1 */ \ + INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */ \ INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */ \ INTEL_VGA_DEVICE(0x590A, info) /* SRV GT1 */ @@ -322,7 +323,9 @@ INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */ #define INTEL_KBL_GT3_IDS(info) \ + INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */ \ + INTEL_VGA_DEVICE(0x5927, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x592B, info), /* Halo GT3 */ \ INTEL_VGA_DEVICE(0x592A, info) /* SRV GT3 */ -- cgit v1.2.3 From a922eb8d4581c883c37ce6e12dca9ff2cb1ea723 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Thu, 23 Jun 2016 14:50:36 -0700 Subject: drm/i915: Removing PCI IDs that are no longer listed as Kabylake. This is unusual. Usually IDs listed on early stages of platform definition are kept there as reserved for later use. However these IDs here are not listed anymore in any of steppings and devices IDs tables for Kabylake on configurations overview section of BSpec. So it is better removing them before they become used in any other future platform. Signed-off-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Link: http://patchwork.freedesktop.org/patch/msgid/1466718636-19675-2-git-send-email-rodrigo.vivi@intel.com --- include/drm/i915_pciids.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 87dde1c48fbf..33466bfc6440 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -325,15 +325,10 @@ #define INTEL_KBL_GT3_IDS(info) \ INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */ \ - INTEL_VGA_DEVICE(0x5927, info), /* ULT GT3 */ \ - INTEL_VGA_DEVICE(0x592B, info), /* Halo GT3 */ \ - INTEL_VGA_DEVICE(0x592A, info) /* SRV GT3 */ + INTEL_VGA_DEVICE(0x5927, info) /* ULT GT3 */ #define INTEL_KBL_GT4_IDS(info) \ - INTEL_VGA_DEVICE(0x5932, info), /* DT GT4 */ \ - INTEL_VGA_DEVICE(0x593B, info), /* Halo GT4 */ \ - INTEL_VGA_DEVICE(0x593A, info), /* SRV GT4 */ \ - INTEL_VGA_DEVICE(0x593D, info) /* WKS GT4 */ + INTEL_VGA_DEVICE(0x593B, info) /* Halo GT4 */ #define INTEL_KBL_IDS(info) \ INTEL_KBL_GT1_IDS(info), \ -- cgit v1.2.3 From 25affa7326554a0e53273f9bb90596a9d8950156 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 13 Jun 2016 12:30:05 +0300 Subject: drm/i915/opregion: add acpi defines from the spec It's easier to read the code when the macro names match the spec. Also add a bunch of missing ones. No functional changes. Reviewed-and-tested-by: Peter Wu Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/7cfdd2733b8cc7abae43cfa8c81aed902b69ecd5.1465810007.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_opregion.c | 37 +++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index f6d8a21d2c49..4ef23e0edc7b 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -232,11 +232,28 @@ struct opregion_asle_ext { #define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19) #define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21) -#define ACPI_OTHER_OUTPUT (0<<8) -#define ACPI_VGA_OUTPUT (1<<8) -#define ACPI_TV_OUTPUT (2<<8) -#define ACPI_DIGITAL_OUTPUT (3<<8) -#define ACPI_LVDS_OUTPUT (4<<8) +/* + * ACPI Specification, Revision 5.0, Appendix B.3.2 _DOD (Enumerate All Devices + * Attached to the Display Adapter). + */ +#define ACPI_DISPLAY_INDEX_SHIFT 0 +#define ACPI_DISPLAY_INDEX_MASK (0xf << 0) +#define ACPI_DISPLAY_PORT_ATTACHMENT_SHIFT 4 +#define ACPI_DISPLAY_PORT_ATTACHMENT_MASK (0xf << 4) +#define ACPI_DISPLAY_TYPE_SHIFT 8 +#define ACPI_DISPLAY_TYPE_MASK (0xf << 8) +#define ACPI_DISPLAY_TYPE_OTHER (0 << 8) +#define ACPI_DISPLAY_TYPE_VGA (1 << 8) +#define ACPI_DISPLAY_TYPE_TV (2 << 8) +#define ACPI_DISPLAY_TYPE_EXTERNAL_DIGITAL (3 << 8) +#define ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL (4 << 8) +#define ACPI_VENDOR_SPECIFIC_SHIFT 12 +#define ACPI_VENDOR_SPECIFIC_MASK (0xf << 12) +#define ACPI_BIOS_CAN_DETECT (1 << 16) +#define ACPI_DEPENDS_ON_VGA (1 << 17) +#define ACPI_PIPE_ID_SHIFT 18 +#define ACPI_PIPE_ID_MASK (7 << 18) +#define ACPI_DEVICE_ID_SCHEME (1 << 31) #define MAX_DSLP 1500 @@ -725,7 +742,7 @@ end: blind_set: i = 0; list_for_each_entry(connector, &dev_priv->dev->mode_config.connector_list, head) { - int output_type = ACPI_OTHER_OUTPUT; + int output_type = ACPI_DISPLAY_TYPE_OTHER; if (i >= max_outputs) { DRM_DEBUG_KMS("More than %u outputs in connector list\n", max_outputs); @@ -734,23 +751,23 @@ blind_set: switch (connector->connector_type) { case DRM_MODE_CONNECTOR_VGA: case DRM_MODE_CONNECTOR_DVIA: - output_type = ACPI_VGA_OUTPUT; + output_type = ACPI_DISPLAY_TYPE_VGA; break; case DRM_MODE_CONNECTOR_Composite: case DRM_MODE_CONNECTOR_SVIDEO: case DRM_MODE_CONNECTOR_Component: case DRM_MODE_CONNECTOR_9PinDIN: - output_type = ACPI_TV_OUTPUT; + output_type = ACPI_DISPLAY_TYPE_TV; break; case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVID: case DRM_MODE_CONNECTOR_DisplayPort: case DRM_MODE_CONNECTOR_HDMIA: case DRM_MODE_CONNECTOR_HDMIB: - output_type = ACPI_DIGITAL_OUTPUT; + output_type = ACPI_DISPLAY_TYPE_EXTERNAL_DIGITAL; break; case DRM_MODE_CONNECTOR_LVDS: - output_type = ACPI_LVDS_OUTPUT; + output_type = ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL; break; } temp = get_did(opregion, i); -- cgit v1.2.3 From c37f7f57cc6ea2e74fc2c73c845c7555b846e05a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 13 Jun 2016 12:30:06 +0300 Subject: drm/i915/opregion: abstract acpi display type getter for a connector No functional changes. Reviewed-and-tested-by: Peter Wu Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/ef19172e5a00d8abd8190a5389283ef6b5f7eaa9.1465810007.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_opregion.c | 58 ++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 4ef23e0edc7b..108cfbf65931 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -674,6 +674,36 @@ static void set_did(struct intel_opregion *opregion, int i, u32 val) } } +static u32 acpi_display_type(struct drm_connector *connector) +{ + u32 display_type = ACPI_DISPLAY_TYPE_OTHER; + + switch (connector->connector_type) { + case DRM_MODE_CONNECTOR_VGA: + case DRM_MODE_CONNECTOR_DVIA: + display_type = ACPI_DISPLAY_TYPE_VGA; + break; + case DRM_MODE_CONNECTOR_Composite: + case DRM_MODE_CONNECTOR_SVIDEO: + case DRM_MODE_CONNECTOR_Component: + case DRM_MODE_CONNECTOR_9PinDIN: + display_type = ACPI_DISPLAY_TYPE_TV; + break; + case DRM_MODE_CONNECTOR_DVII: + case DRM_MODE_CONNECTOR_DVID: + case DRM_MODE_CONNECTOR_DisplayPort: + case DRM_MODE_CONNECTOR_HDMIA: + case DRM_MODE_CONNECTOR_HDMIB: + display_type = ACPI_DISPLAY_TYPE_EXTERNAL_DIGITAL; + break; + case DRM_MODE_CONNECTOR_LVDS: + display_type = ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL; + break; + } + + return display_type; +} + static void intel_didl_outputs(struct drm_i915_private *dev_priv) { struct intel_opregion *opregion = &dev_priv->opregion; @@ -742,36 +772,16 @@ end: blind_set: i = 0; list_for_each_entry(connector, &dev_priv->dev->mode_config.connector_list, head) { - int output_type = ACPI_DISPLAY_TYPE_OTHER; + int display_type = acpi_display_type(connector); + if (i >= max_outputs) { DRM_DEBUG_KMS("More than %u outputs in connector list\n", max_outputs); return; } - switch (connector->connector_type) { - case DRM_MODE_CONNECTOR_VGA: - case DRM_MODE_CONNECTOR_DVIA: - output_type = ACPI_DISPLAY_TYPE_VGA; - break; - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: - case DRM_MODE_CONNECTOR_9PinDIN: - output_type = ACPI_DISPLAY_TYPE_TV; - break; - case DRM_MODE_CONNECTOR_DVII: - case DRM_MODE_CONNECTOR_DVID: - case DRM_MODE_CONNECTOR_DisplayPort: - case DRM_MODE_CONNECTOR_HDMIA: - case DRM_MODE_CONNECTOR_HDMIB: - output_type = ACPI_DISPLAY_TYPE_EXTERNAL_DIGITAL; - break; - case DRM_MODE_CONNECTOR_LVDS: - output_type = ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL; - break; - } + temp = get_did(opregion, i); - set_did(opregion, i, temp | (1 << 31) | output_type | i); + set_did(opregion, i, temp | (1 << 31) | display_type | i); i++; } goto end; -- cgit v1.2.3 From bb9c1b976150f62e36165eb4af2afe4c66533d08 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 13 Jun 2016 12:30:07 +0300 Subject: drm/i915/opregion: handle missing connector types for acpi display types Most notably eDP, DSI, and TV. Add MISSING_CASE handling so we won't miss this in the future. Reviewed-and-tested-by: Peter Wu Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/5773794027ea0d699052a343491b52343ba30504.1465810007.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_opregion.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 108cfbf65931..82e687dd09c3 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -676,7 +676,7 @@ static void set_did(struct intel_opregion *opregion, int i, u32 val) static u32 acpi_display_type(struct drm_connector *connector) { - u32 display_type = ACPI_DISPLAY_TYPE_OTHER; + u32 display_type; switch (connector->connector_type) { case DRM_MODE_CONNECTOR_VGA: @@ -687,6 +687,7 @@ static u32 acpi_display_type(struct drm_connector *connector) case DRM_MODE_CONNECTOR_SVIDEO: case DRM_MODE_CONNECTOR_Component: case DRM_MODE_CONNECTOR_9PinDIN: + case DRM_MODE_CONNECTOR_TV: display_type = ACPI_DISPLAY_TYPE_TV; break; case DRM_MODE_CONNECTOR_DVII: @@ -697,8 +698,18 @@ static u32 acpi_display_type(struct drm_connector *connector) display_type = ACPI_DISPLAY_TYPE_EXTERNAL_DIGITAL; break; case DRM_MODE_CONNECTOR_LVDS: + case DRM_MODE_CONNECTOR_eDP: + case DRM_MODE_CONNECTOR_DSI: display_type = ACPI_DISPLAY_TYPE_INTERNAL_DIGITAL; break; + case DRM_MODE_CONNECTOR_Unknown: + case DRM_MODE_CONNECTOR_VIRTUAL: + display_type = ACPI_DISPLAY_TYPE_OTHER; + break; + default: + MISSING_CASE(connector->connector_type); + display_type = ACPI_DISPLAY_TYPE_OTHER; + break; } return display_type; -- cgit v1.2.3 From c68b0ab2e08fd8913a794d11e74cbf5cd589b3df Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 28 Jun 2016 12:51:49 +0100 Subject: drm/i915/debug: Select PREEMPT_COUNT when enabling debugging Required to enable correct wait_for_atomic checks. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/Kconfig.debug | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index 8f404103341d..43400adc95db 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -18,6 +18,7 @@ config DRM_I915_WERROR config DRM_I915_DEBUG bool "Enable additional driver debugging" depends on DRM_I915 + select PREEMPT_COUNT default n help Choose this option to turn on extra driver debugging that may affect -- cgit v1.2.3 From 18f4b8435c50888bb36cf8de3b7f0075f00dc12c Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 12:27:22 +0100 Subject: drm/i915: Use atomic waits for short non-atomic ones usleep_range is not recommended for waits shorten than 10us. Make the wait_for_us use the atomic variant for such waits. To do so we need to reimplement the _wait_for_atomic macro to be safe with regards to preemption and interrupts. v2: Reimplement _wait_for_atomic to be irq and preemption safe. (Chris Wilson and Imre Deak) v3: Fixed in_atomic check due rebase error. v4: Build bug on non-constant timeouts. v5: Compile away cpu migration code in atomic paths. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Cc: Imre Deak Cc: Mika Kuoppala Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467114710-29989-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_drv.h | 62 ++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3156d8df7921..98a5be4ec8c5 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -69,39 +69,63 @@ }) #define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 1000) -#define wait_for_us(COND, US) _wait_for((COND), (US), 1) /* If CONFIG_PREEMPT_COUNT is disabled, in_atomic() always reports false. */ #if defined(CONFIG_DRM_I915_DEBUG) && defined(CONFIG_PREEMPT_COUNT) -# define _WAIT_FOR_ATOMIC_CHECK WARN_ON_ONCE(!in_atomic()) +# define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) WARN_ON_ONCE((ATOMIC) && !in_atomic()) #else -# define _WAIT_FOR_ATOMIC_CHECK do { } while (0) +# define _WAIT_FOR_ATOMIC_CHECK(ATOMIC) do { } while (0) #endif -#define _wait_for_atomic(COND, US) ({ \ - unsigned long end__; \ - int ret__ = 0; \ - _WAIT_FOR_ATOMIC_CHECK; \ +#define _wait_for_atomic(COND, US, ATOMIC) \ +({ \ + int cpu, ret, timeout = (US) * 1000; \ + u64 base; \ + _WAIT_FOR_ATOMIC_CHECK(ATOMIC); \ BUILD_BUG_ON((US) > 50000); \ - end__ = (local_clock() >> 10) + (US) + 1; \ - while (!(COND)) { \ - if (time_after((unsigned long)(local_clock() >> 10), end__)) { \ - /* Unlike the regular wait_for(), this atomic variant \ - * cannot be preempted (and we'll just ignore the issue\ - * of irq interruptions) and so we know that no time \ - * has passed since the last check of COND and can \ - * immediately report the timeout. \ - */ \ - ret__ = -ETIMEDOUT; \ + if (!(ATOMIC)) { \ + preempt_disable(); \ + cpu = smp_processor_id(); \ + } \ + base = local_clock(); \ + for (;;) { \ + u64 now = local_clock(); \ + if (!(ATOMIC)) \ + preempt_enable(); \ + if (COND) { \ + ret = 0; \ + break; \ + } \ + if (now - base >= timeout) { \ + ret = -ETIMEDOUT; \ break; \ } \ cpu_relax(); \ + if (!(ATOMIC)) { \ + preempt_disable(); \ + if (unlikely(cpu != smp_processor_id())) { \ + timeout -= now - base; \ + cpu = smp_processor_id(); \ + base = local_clock(); \ + } \ + } \ } \ + ret; \ +}) + +#define wait_for_us(COND, US) \ +({ \ + int ret__; \ + BUILD_BUG_ON(!__builtin_constant_p(US)); \ + if ((US) > 10) \ + ret__ = _wait_for((COND), (US), 10); \ + else \ + ret__ = _wait_for_atomic((COND), (US), 0); \ ret__; \ }) -#define wait_for_atomic(COND, MS) _wait_for_atomic((COND), (MS) * 1000) -#define wait_for_atomic_us(COND, US) _wait_for_atomic((COND), (US)) +#define wait_for_atomic(COND, MS) _wait_for_atomic((COND), (MS) * 1000, 1) +#define wait_for_atomic_us(COND, US) _wait_for_atomic((COND), (US), 1) #define KHz(x) (1000 * (x)) #define MHz(x) KHz(1000 * (x)) -- cgit v1.2.3 From 0c5eed651455d0c52b5f6a387fd11b0a690bf24c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 29 Jun 2016 15:51:14 +0100 Subject: drm/i915: Remove request->reset_counter Since commit 2ed53a94d8cb ("drm/i915: On GPU reset, set the HWS breadcrumb to the last seqno") once a hang is completed, the seqno is advanced past all current requests. With this we know that if we wake up from waiting for a request, if a hang has occurred and reset completed, our request will be considered complete (i.e. i915_gem_request_completed() returns true). Therefore we only need to worry about the situation where a hang has occurred, but not yet reset, where we may need to release our struct_mutex. Since we don't need to detect the completed reset using the global gpu_error->reset_counter anymore, we do not need to track the reset_counter epoch inside the request. Signed-off-by: Chris Wilson Cc: Arun Siluvery Cc: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1467211874-11552-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Arun Siluvery --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_gem.c | 16 ++++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 724d34b00196..82b20e14b065 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2368,7 +2368,6 @@ struct drm_i915_gem_request { /** On Which ring this request was generated */ struct drm_i915_private *i915; struct intel_engine_cs *engine; - unsigned reset_counter; /** GEM sequence number associated with the previous request, * when the HWS breadcrumb is equal to this the GPU is processing diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 51191b879747..1d9878258103 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1506,12 +1506,13 @@ int __i915_wait_request(struct drm_i915_gem_request *req, /* We need to check whether any gpu reset happened in between * the request being submitted and now. If a reset has occurred, - * the request is effectively complete (we either are in the - * process of or have discarded the rendering and completely - * reset the GPU. The results of the request are lost and we - * are free to continue on with the original operation. + * the seqno will have been advance past ours and our request + * is complete. If we are in the process of handling a reset, + * the request is effectively complete as the rendering will + * be discarded, but we need to return in order to drop the + * struct_mutex. */ - if (req->reset_counter != i915_reset_counter(&dev_priv->gpu_error)) { + if (i915_reset_in_progress(&dev_priv->gpu_error)) { ret = 0; break; } @@ -1685,7 +1686,7 @@ i915_wait_request(struct drm_i915_gem_request *req) return ret; /* If the GPU hung, we want to keep the requests to find the guilty. */ - if (req->reset_counter == i915_reset_counter(&dev_priv->gpu_error)) + if (!i915_reset_in_progress(&dev_priv->gpu_error)) __i915_gem_request_retire__upto(req); return 0; @@ -1746,7 +1747,7 @@ i915_gem_object_retire_request(struct drm_i915_gem_object *obj, else if (obj->last_write_req == req) i915_gem_object_retire__write(obj); - if (req->reset_counter == i915_reset_counter(&req->i915->gpu_error)) + if (!i915_reset_in_progress(&req->i915->gpu_error)) __i915_gem_request_retire__upto(req); } @@ -3021,7 +3022,6 @@ __i915_gem_request_alloc(struct intel_engine_cs *engine, kref_init(&req->ref); req->i915 = dev_priv; req->engine = engine; - req->reset_counter = reset_counter; req->ctx = ctx; i915_gem_context_reference(req->ctx); -- cgit v1.2.3 From 527b6abe5fd2d24fba69e9564a2d608e1796ca8d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 13:44:03 +0100 Subject: Revert "drm/i915: Use atomic commits for legacy page_flips" This reverts commit ee042aa40b66d18d465206845b0752c6a617ba3f. Something appears to be off in the timing, but as far as I can tell it is not along the event delivery path. The net effect appears to be rendering flicker (the current render buffer appears on the scanout, with what appears to be active rendering for a fraction of a frame) and is causing me a headache. The cursor is also being stalled by page flips, causing a "heavy mouse" and jitter. Daniel Stone did find what appears to the cause of the tearing, in https://lists.freedesktop.org/archives/intel-gfx/2016-June/099466.html That is the parameter passed to intel_atomic_commit_tail is the old_state but we need the new_state to wait upon. That leaves the question of how the CRC based tests didn't spot the error (how can we improve our tests?), the issue of legacy cursor stalling flips, and the issue of flips stalling the cursor. For the moment, step back until the condundrum of new/old state is reviewed along with more tests! Reported-and-tested-by: Steven Newbury Reported-by: Rafael Ristovski Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96593 Testcase: igt/kms_cursor_legacy/basic-cursor-vs-flip Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466772243-21879-1-git-send-email-chris@chris-wilson.co.uk Acked-by: Maarten Lankhorst --- drivers/gpu/drm/i915/intel_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d902a70edb84..2acc6060b78d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11646,7 +11646,6 @@ void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe) spin_unlock(&dev->event_lock); } -__maybe_unused static int intel_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, @@ -14008,7 +14007,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .set_property = drm_atomic_helper_crtc_set_property, .destroy = intel_crtc_destroy, - .page_flip = drm_atomic_helper_page_flip, + .page_flip = intel_crtc_page_flip, .atomic_duplicate_state = intel_crtc_duplicate_state, .atomic_destroy_state = intel_crtc_destroy_state, }; -- cgit v1.2.3 From 1758b90e38f53b93821c908201826e825a37cb65 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:44 +0100 Subject: drm/i915: Use a hybrid scheme for fast register waits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ville Syrjälä reported that in the majority of wait_for(I915_READ()) he inspect, most completed within the first couple of reads and that the delay between those wait_for() reads was the ratelimiting step for many code paths. For example, __gen6_update_ring_freq() was blamed for slowing down boot by many milliseconds, but under Ville's scrutiny the issue was just excessive delay waiting for sandybridge_pcode_write(). We can eliminate the wait by initially using a busyspin upon the register read and only fallback to the sleeping loop in cases where the hardware is indeed too slow. A threshold of 2 microseconds is used as the initial ballpark. To avoid excessive code bloating from converting every wait_for() into a hybrid busy/sleep loop, we extend wait_for_register_fw() and export it for use by other callers. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Ville Syrjälä Cc: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 11 +++++ drivers/gpu/drm/i915/intel_uncore.c | 83 ++++++++++++++++++++++++++++++++----- 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 82b20e14b065..48d30676455e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2968,6 +2968,17 @@ u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv); void assert_forcewakes_inactive(struct drm_i915_private *dev_priv); +int intel_wait_for_register(struct drm_i915_private *dev_priv, + i915_reg_t reg, + const u32 mask, + const u32 value, + const unsigned long timeout_ms); +int intel_wait_for_register_fw(struct drm_i915_private *dev_priv, + i915_reg_t reg, + const u32 mask, + const u32 value, + const unsigned long timeout_ms); + static inline bool intel_gvt_active(struct drm_i915_private *dev_priv) { return dev_priv->gvt.initialized; diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index c1ca458d688e..4c166f6550be 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1609,13 +1609,74 @@ static int gen6_reset_engines(struct drm_i915_private *dev_priv, return ret; } -static int wait_for_register_fw(struct drm_i915_private *dev_priv, - i915_reg_t reg, - const u32 mask, - const u32 value, - const unsigned long timeout_ms) +/** + * intel_wait_for_register_fw - wait until register matches expected state + * @dev_priv: the i915 device + * @reg: the register to read + * @mask: mask to apply to register value + * @value: expected value + * @timeout_ms: timeout in millisecond + * + * This routine waits until the target register @reg contains the expected + * @value after applying the @mask, i.e. it waits until + * (I915_READ_FW(@reg) & @mask) == @value + * Otherwise, the wait will timeout after @timeout_ms milliseconds. + * + * Note that this routine assumes the caller holds forcewake asserted, it is + * not suitable for very long waits. See intel_wait_for_register() if you + * wish to wait without holding forcewake for the duration (i.e. you expect + * the wait to be slow). + * + * Returns 0 if the register matches the desired condition, or -ETIMEOUT. + */ +int intel_wait_for_register_fw(struct drm_i915_private *dev_priv, + i915_reg_t reg, + const u32 mask, + const u32 value, + const unsigned long timeout_ms) +{ +#define done ((I915_READ_FW(reg) & mask) == value) + int ret = wait_for_us(done, 2); + if (ret) + ret = wait_for(done, timeout_ms); + return ret; +#undef done +} + +/** + * intel_wait_for_register - wait until register matches expected state + * @dev_priv: the i915 device + * @reg: the register to read + * @mask: mask to apply to register value + * @value: expected value + * @timeout_ms: timeout in millisecond + * + * This routine waits until the target register @reg contains the expected + * @value after applying the @mask, i.e. it waits until + * (I915_READ(@reg) & @mask) == @value + * Otherwise, the wait will timeout after @timeout_ms milliseconds. + * + * Returns 0 if the register matches the desired condition, or -ETIMEOUT. + */ +int intel_wait_for_register(struct drm_i915_private *dev_priv, + i915_reg_t reg, + const u32 mask, + const u32 value, + const unsigned long timeout_ms) { - return wait_for((I915_READ_FW(reg) & mask) == value, timeout_ms); + + unsigned fw = + intel_uncore_forcewake_for_reg(dev_priv, reg, FW_REG_READ); + int ret; + + intel_uncore_forcewake_get(dev_priv, fw); + ret = wait_for_us((I915_READ_FW(reg) & mask) == value, 2); + intel_uncore_forcewake_put(dev_priv, fw); + if (ret) + ret = wait_for((I915_READ_NOTRACE(reg) & mask) == value, + timeout_ms); + + return ret; } static int gen8_request_engine_reset(struct intel_engine_cs *engine) @@ -1626,11 +1687,11 @@ static int gen8_request_engine_reset(struct intel_engine_cs *engine) I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base), _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)); - ret = wait_for_register_fw(dev_priv, - RING_RESET_CTL(engine->mmio_base), - RESET_CTL_READY_TO_RESET, - RESET_CTL_READY_TO_RESET, - 700); + ret = intel_wait_for_register_fw(dev_priv, + RING_RESET_CTL(engine->mmio_base), + RESET_CTL_READY_TO_RESET, + RESET_CTL_READY_TO_RESET, + 700); if (ret) DRM_ERROR("%s: reset request timeout\n", engine->name); -- cgit v1.2.3 From 3f5582dd845be5af2d1de01b99796abda9ecbdd9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:45 +0100 Subject: drm/i915: Convert sandybridge_pcode_*() to use intel_wait_for_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to replace the inline wait_for() with an out-of-line hybrid busy/sleep wait_for() in the hopes of speeding up the communication wit the PCode unit. Indeed, on my i5-2500s, __gen6_update_ring_freq improves from 6,080,661ns to 8172ns. v2: Missed using _fw variants for sandybridge_pcode_read() Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Ville Syrjälä Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_pm.c | 43 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d7f8ba89d2a5..870085ab5423 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7623,46 +7623,59 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val { WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); - if (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) { + /* GEN6_PCODE_* are outside of the forcewake domain, we can + * use te fw I915_READ variants to reduce the amount of work + * required when reading/writing. + */ + + if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) { DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed\n"); return -EAGAIN; } - I915_WRITE(GEN6_PCODE_DATA, *val); - I915_WRITE(GEN6_PCODE_DATA1, 0); - I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); + I915_WRITE_FW(GEN6_PCODE_DATA, *val); + I915_WRITE_FW(GEN6_PCODE_DATA1, 0); + I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); - if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, - 500)) { + if (intel_wait_for_register_fw(dev_priv, + GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0, + 500)) { DRM_ERROR("timeout waiting for pcode read (%d) to finish\n", mbox); return -ETIMEDOUT; } - *val = I915_READ(GEN6_PCODE_DATA); - I915_WRITE(GEN6_PCODE_DATA, 0); + *val = I915_READ_FW(GEN6_PCODE_DATA); + I915_WRITE_FW(GEN6_PCODE_DATA, 0); return 0; } -int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val) +int sandybridge_pcode_write(struct drm_i915_private *dev_priv, + u32 mbox, u32 val) { WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); - if (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) { + /* GEN6_PCODE_* are outside of the forcewake domain, we can + * use te fw I915_READ variants to reduce the amount of work + * required when reading/writing. + */ + + if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) { DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed\n"); return -EAGAIN; } - I915_WRITE(GEN6_PCODE_DATA, val); - I915_WRITE(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); + I915_WRITE_FW(GEN6_PCODE_DATA, val); + I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox); - if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, - 500)) { + if (intel_wait_for_register_fw(dev_priv, + GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0, + 500)) { DRM_ERROR("timeout waiting for pcode write (%d) to finish\n", mbox); return -ETIMEDOUT; } - I915_WRITE(GEN6_PCODE_DATA, 0); + I915_WRITE_FW(GEN6_PCODE_DATA, 0); return 0; } -- cgit v1.2.3 From c6ddc5f3d05dfc7bbb2a5f1e477aed98510a71bb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:46 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-3-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b98afbd33235..51eb1cd86957 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2535,8 +2535,6 @@ int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on) u32 val; int err; -#define COND (I915_READ(VLV_GTLC_SURVIVABILITY_REG) & VLV_GFX_CLK_STATUS_BIT) - val = I915_READ(VLV_GTLC_SURVIVABILITY_REG); val &= ~VLV_GFX_CLK_FORCE_ON_BIT; if (force_on) @@ -2546,13 +2544,16 @@ int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on) if (!force_on) return 0; - err = wait_for(COND, 20); + err = intel_wait_for_register(dev_priv, + VLV_GTLC_SURVIVABILITY_REG, + VLV_GFX_CLK_STATUS_BIT, + VLV_GFX_CLK_STATUS_BIT, + 20); if (err) DRM_ERROR("timeout waiting for GFX clock force-on (%08x)\n", I915_READ(VLV_GTLC_SURVIVABILITY_REG)); return err; -#undef COND } static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow) -- cgit v1.2.3 From b2736695886931ede25de3d21726dea7b2e8e9f2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:47 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-4-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 51eb1cd86957..fb5758f4f9d3 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2568,13 +2568,15 @@ static int vlv_allow_gt_wake(struct drm_i915_private *dev_priv, bool allow) I915_WRITE(VLV_GTLC_WAKE_CTRL, val); POSTING_READ(VLV_GTLC_WAKE_CTRL); -#define COND (!!(I915_READ(VLV_GTLC_PW_STATUS) & VLV_GTLC_ALLOWWAKEACK) == \ - allow) - err = wait_for(COND, 1); + err = intel_wait_for_register(dev_priv, + VLV_GTLC_PW_STATUS, + VLV_GTLC_ALLOWWAKEACK, + allow, + 1); if (err) DRM_ERROR("timeout disabling GT waking\n"); + return err; -#undef COND } static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv, -- cgit v1.2.3 From 41ce405e689491658cb68dfca620dc199130c5f6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:48 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-5-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index fb5758f4f9d3..c580e24095b0 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2588,8 +2588,7 @@ static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv, mask = VLV_GTLC_PW_MEDIA_STATUS_MASK | VLV_GTLC_PW_RENDER_STATUS_MASK; val = wait_for_on ? mask : 0; -#define COND ((I915_READ(VLV_GTLC_PW_STATUS) & mask) == val) - if (COND) + if ((I915_READ(VLV_GTLC_PW_STATUS) & mask) == val) return 0; DRM_DEBUG_KMS("waiting for GT wells to go %s (%08x)\n", @@ -2600,13 +2599,14 @@ static int vlv_wait_for_gt_wells(struct drm_i915_private *dev_priv, * RC6 transitioning can be delayed up to 2 msec (see * valleyview_enable_rps), use 3 msec for safety. */ - err = wait_for(COND, 3); + err = intel_wait_for_register(dev_priv, + VLV_GTLC_PW_STATUS, mask, val, + 3); if (err) DRM_ERROR("timeout waiting for GT wells to go %s\n", onoff(wait_for_on)); return err; -#undef COND } static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From e1672d1cf66ae05ff6bbdd2a5f65a8e709e059bb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:49 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-6-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_crt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 165e4b901548..2aa85cf4b3cf 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -301,8 +301,10 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) I915_WRITE(crt->adpa_reg, adpa); - if (wait_for((I915_READ(crt->adpa_reg) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, - 1000)) + if (intel_wait_for_register(dev_priv, + crt->adpa_reg, + ADPA_CRT_HOTPLUG_FORCE_TRIGGER, 0, + 1000)) DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); if (turn_off_dac) { -- cgit v1.2.3 From a522ae4bb6e19e3072bb79fdcf692cae6507f9fc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:50 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-7-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_crt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 2aa85cf4b3cf..ccfb0dd09d2f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -340,8 +340,10 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) I915_WRITE(crt->adpa_reg, adpa); - if (wait_for((I915_READ(crt->adpa_reg) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, - 1000)) { + if (intel_wait_for_register(dev_priv, + crt->adpa_reg, + ADPA_CRT_HOTPLUG_FORCE_TRIGGER, 0, + 1000)) { DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); I915_WRITE(crt->adpa_reg, save_adpa); } -- cgit v1.2.3 From fd3790d41b3443c99a0d40674dad5da89a44ff4d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:51 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-8-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_crt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index ccfb0dd09d2f..0c8036e1b4d7 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -398,9 +398,9 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) CRT_HOTPLUG_FORCE_DETECT, CRT_HOTPLUG_FORCE_DETECT); /* wait for FORCE_DETECT to go off */ - if (wait_for((I915_READ(PORT_HOTPLUG_EN) & - CRT_HOTPLUG_FORCE_DETECT) == 0, - 1000)) + if (intel_wait_for_register(dev_priv, PORT_HOTPLUG_EN, + CRT_HOTPLUG_FORCE_DETECT, 0, + 1000)) DRM_DEBUG_KMS("timed out waiting for FORCE_DETECT to go off"); } -- cgit v1.2.3 From 058fee93e286e42bdd441ffe9b8ee1209de8ebab Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:52 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-9-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ddi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ad3b0ee5e55b..6bcd7ffbff43 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1808,7 +1808,10 @@ static u32 bxt_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy) static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv, enum dpio_phy phy) { - if (wait_for(I915_READ(BXT_PORT_REF_DW3(phy)) & GRC_DONE, 10)) + if (intel_wait_for_register(dev_priv, + BXT_PORT_REF_DW3(phy), + GRC_DONE, GRC_DONE, + 10)) DRM_ERROR("timeout waiting for PHY%d GRC\n", phy); } -- cgit v1.2.3 From b8511f534cd0f5f8b03f361840824764353448c6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:53 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-10-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2acc6060b78d..a501d850c6d5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1124,8 +1124,9 @@ static void intel_wait_for_pipe_off(struct intel_crtc *crtc) i915_reg_t reg = PIPECONF(cpu_transcoder); /* Wait for the Pipe State to go off */ - if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, - 100)) + if (intel_wait_for_register(dev_priv, + reg, I965_PIPECONF_ACTIVE, 0, + 100)) WARN(1, "pipe_off wait timed out\n"); } else { /* Wait for the display line to settle */ -- cgit v1.2.3 From 2c30b43b59c5662aaacd6ec9a6b3f55124121746 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:54 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-11-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a501d850c6d5..cf93bb2a2ac3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1545,7 +1545,11 @@ static void _vlv_enable_pll(struct intel_crtc *crtc, POSTING_READ(DPLL(pipe)); udelay(150); - if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) + if (intel_wait_for_register(dev_priv, + DPLL(pipe), + DPLL_LOCK_VLV, + DPLL_LOCK_VLV, + 1)) DRM_ERROR("DPLL %d failed to lock\n", pipe); } -- cgit v1.2.3 From 6b18826a9e656d6e2d791ae925752323e92f706b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:55 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-12-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cf93bb2a2ac3..fc0794de595b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1598,7 +1598,9 @@ static void _chv_enable_pll(struct intel_crtc *crtc, I915_WRITE(DPLL(pipe), pipe_config->dpll_hw_state.dpll); /* Check PLL is locked */ - if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) + if (intel_wait_for_register(dev_priv, + DPLL(pipe), DPLL_LOCK_VLV, DPLL_LOCK_VLV, + 1)) DRM_ERROR("PLL %d failed to lock\n", pipe); } -- cgit v1.2.3 From 370004d38abc65bf920ae188be72caa7c7572033 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:56 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-13-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fc0794de595b..1be0c02f5b4d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1820,7 +1820,9 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv, BUG(); } - if (wait_for((I915_READ(dpll_reg) & port_mask) == expected_mask, 1000)) + if (intel_wait_for_register(dev_priv, + dpll_reg, port_mask, expected_mask, + 1000)) WARN(1, "timed out waiting for port %c ready: got 0x%x, expected 0x%x\n", port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask); } -- cgit v1.2.3 From 650fbd8481ed365f7da03478c784cf3f07a58b20 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:57 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-14-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1be0c02f5b4d..1c34d4039d7b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1880,7 +1880,9 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, val |= TRANS_PROGRESSIVE; I915_WRITE(reg, val | TRANS_ENABLE); - if (wait_for(I915_READ(reg) & TRANS_STATE_ENABLE, 100)) + if (intel_wait_for_register(dev_priv, + reg, TRANS_STATE_ENABLE, TRANS_STATE_ENABLE, + 100)) DRM_ERROR("failed to enable transcoder %c\n", pipe_name(pipe)); } -- cgit v1.2.3 From d9f96244b88ec68ec459d3c8110a2be7a6e9d841 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:58 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-15-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1c34d4039d7b..50ad3c55f0a9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1910,7 +1910,11 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, val |= TRANS_PROGRESSIVE; I915_WRITE(LPT_TRANSCONF, val); - if (wait_for(I915_READ(LPT_TRANSCONF) & TRANS_STATE_ENABLE, 100)) + if (intel_wait_for_register(dev_priv, + LPT_TRANSCONF, + TRANS_STATE_ENABLE, + TRANS_STATE_ENABLE, + 100)) DRM_ERROR("Failed to enable PCH transcoder\n"); } -- cgit v1.2.3 From a7d04662358daf44c4fe61d1f27bbaeca7cd126e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:32:59 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-16-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 50ad3c55f0a9..99e8c8ea7f00 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1937,7 +1937,9 @@ static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv, val &= ~TRANS_ENABLE; I915_WRITE(reg, val); /* wait for PCH transcoder off, transcoder state */ - if (wait_for((I915_READ(reg) & TRANS_STATE_ENABLE) == 0, 50)) + if (intel_wait_for_register(dev_priv, + reg, TRANS_STATE_ENABLE, 0, + 50)) DRM_ERROR("failed to disable transcoder %c\n", pipe_name(pipe)); if (HAS_PCH_CPT(dev)) { -- cgit v1.2.3 From dfdb47497ca0c4f5983e926dc8a3e313440aeb69 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:00 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-17-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 99e8c8ea7f00..187e703a1c45 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1959,7 +1959,9 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) val &= ~TRANS_ENABLE; I915_WRITE(LPT_TRANSCONF, val); /* wait for PCH transcoder off, transcoder state */ - if (wait_for((I915_READ(LPT_TRANSCONF) & TRANS_STATE_ENABLE) == 0, 50)) + if (intel_wait_for_register(dev_priv, + LPT_TRANSCONF, TRANS_STATE_ENABLE, 0, + 50)) DRM_ERROR("Failed to disable PCH transcoder\n"); /* Workaround: clear timing override bit. */ -- cgit v1.2.3 From 2ec9ba3cffd08c6d78e1ed1fd0188efe7fcaec1c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:01 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-18-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 187e703a1c45..cb7d49c34eb3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4465,7 +4465,9 @@ void hsw_enable_ips(struct intel_crtc *crtc) * and don't wait for vblanks until the end of crtc_enable, then * the HW state readout code will complain that the expected * IPS_CTL value is not the one we read. */ - if (wait_for(I915_READ_NOTRACE(IPS_CTL) & IPS_ENABLE, 50)) + if (intel_wait_for_register(dev_priv, + IPS_CTL, IPS_ENABLE, IPS_ENABLE, + 50)) DRM_ERROR("Timed out waiting for IPS enable\n"); } } -- cgit v1.2.3 From b85c1ecf512b37ae16fc9bbd834ed67df345a69e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:02 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-19-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cb7d49c34eb3..8658c02e92f1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4486,7 +4486,9 @@ void hsw_disable_ips(struct intel_crtc *crtc) WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0)); mutex_unlock(&dev_priv->rps.hw_lock); /* wait for pcode to finish disabling IPS, which may take up to 42ms */ - if (wait_for((I915_READ(IPS_CTL) & IPS_ENABLE) == 0, 42)) + if (intel_wait_for_register(dev_priv, + IPS_CTL, IPS_ENABLE, 0, + 42)) DRM_ERROR("Timed out waiting for IPS disable\n"); } else { I915_WRITE(IPS_CTL, 0); -- cgit v1.2.3 From 95cac28301072f884fe4b759d9022c002cb4c518 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:03 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-20-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8658c02e92f1..d64c393bf42c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5418,7 +5418,9 @@ static void bxt_de_pll_disable(struct drm_i915_private *dev_priv) I915_WRITE(BXT_DE_PLL_ENABLE, 0); /* Timeout 200us */ - if (wait_for((I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) == 0, 1)) + if (intel_wait_for_register(dev_priv, + BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 0, + 1)) DRM_ERROR("timeout waiting for DE PLL unlock\n"); dev_priv->cdclk_pll.vco = 0; -- cgit v1.2.3 From e084e1b9cc1bb0717aaeccccec640e28cc141560 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:04 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-21-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d64c393bf42c..f61ca97f9fb8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5439,7 +5439,11 @@ static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco) I915_WRITE(BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE); /* Timeout 200us */ - if (wait_for((I915_READ(BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) != 0, 1)) + if (intel_wait_for_register(dev_priv, + BXT_DE_PLL_ENABLE, + BXT_DE_PLL_LOCK, + BXT_DE_PLL_LOCK, + 1)) DRM_ERROR("timeout waiting for DE PLL lock\n"); dev_priv->cdclk_pll.vco = vco; -- cgit v1.2.3 From e24ca054b065bf1dd5e36da7a29301e8797636ae Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:05 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-22-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f61ca97f9fb8..f47643da0ad1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5706,7 +5706,9 @@ skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco) I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) | LCPLL_PLL_ENABLE); - if (wait_for(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK, 5)) + if (intel_wait_for_register(dev_priv, + LCPLL1_CTL, LCPLL_PLL_LOCK, LCPLL_PLL_LOCK, + 5)) DRM_ERROR("DPLL0 not locked\n"); dev_priv->cdclk_pll.vco = vco; -- cgit v1.2.3 From 8ad32a05b5f0bc28144d79e2b1ef36f8159cca38 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:06 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-23-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f47643da0ad1..f6531137766f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5721,7 +5721,9 @@ static void skl_dpll0_disable(struct drm_i915_private *dev_priv) { I915_WRITE(LCPLL1_CTL, I915_READ(LCPLL1_CTL) & ~LCPLL_PLL_ENABLE); - if (wait_for(!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_LOCK), 1)) + if (intel_wait_for_register(dev_priv, + LCPLL1_CTL, LCPLL_PLL_LOCK, 0, + 1)) DRM_ERROR("Couldn't disable DPLL0\n"); dev_priv->cdclk_pll.vco = 0; -- cgit v1.2.3 From 24d8441d46ad453e71b2a6e58f96800e80dca822 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:07 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-24-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f6531137766f..5fa37aaf7e51 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9578,7 +9578,7 @@ static void hsw_disable_lcpll(struct drm_i915_private *dev_priv, I915_WRITE(LCPLL_CTL, val); POSTING_READ(LCPLL_CTL); - if (wait_for((I915_READ(LCPLL_CTL) & LCPLL_PLL_LOCK) == 0, 1)) + if (intel_wait_for_register(dev_priv, LCPLL_CTL, LCPLL_PLL_LOCK, 0, 1)) DRM_ERROR("LCPLL still locked\n"); val = hsw_read_dcomp(dev_priv); -- cgit v1.2.3 From 93220c08edfea2af75bc8948729424ccc3a93942 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:08 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-25-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5fa37aaf7e51..30c181a72202 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9633,7 +9633,9 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) val &= ~LCPLL_PLL_DISABLE; I915_WRITE(LCPLL_CTL, val); - if (wait_for(I915_READ(LCPLL_CTL) & LCPLL_PLL_LOCK, 5)) + if (intel_wait_for_register(dev_priv, + LCPLL_CTL, LCPLL_PLL_LOCK, LCPLL_PLL_LOCK, + 5)) DRM_ERROR("LCPLL not locked yet\n"); if (val & LCPLL_CD_SOURCE_FCLK) { -- cgit v1.2.3 From 9036ff06c2d82225ac29fc0b9c61b90bbd434c29 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:09 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-26-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6d586b72da88..f1a817ed134d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1768,8 +1768,9 @@ static void wait_panel_status(struct intel_dp *intel_dp, I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg)); - if (_wait_for((I915_READ(pp_stat_reg) & mask) == value, - 5 * USEC_PER_SEC, 10 * USEC_PER_MSEC)) + if (intel_wait_for_register(dev_priv, + pp_stat_reg, mask, value, + 5000)) DRM_ERROR("Panel status timeout: status %08x control %08x\n", I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg)); -- cgit v1.2.3 From a767017f4888a714419b62d5bf02021e46d88e47 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:10 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-27-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f1a817ed134d..0757ee427ad7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3322,8 +3322,10 @@ void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) if (port == PORT_A) return; - if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_IDLE_DONE), - 1)) + if (intel_wait_for_register(dev_priv,DP_TP_STATUS(port), + DP_TP_STATUS_IDLE_DONE, + DP_TP_STATUS_IDLE_DONE, + 1)) DRM_ERROR("Timed out waiting for DP idle patterns\n"); } -- cgit v1.2.3 From 3016a31ffe7db05e336420a58cb0cfe6f71159f9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:11 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-28-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dp_mst.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 5f88e12575ac..c1d318601bf1 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -213,8 +213,11 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder) DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); - if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_ACT_SENT), - 1)) + if (intel_wait_for_register(dev_priv, + DP_TP_STATUS(port), + DP_TP_STATUS_ACT_SENT, + DP_TP_STATUS_ACT_SENT, + 1)) DRM_ERROR("Timed out waiting for ACT sent\n"); ret = drm_dp_check_act_status(&intel_dp->mst_mgr); -- cgit v1.2.3 From 27bf23a9113dd3aafbd0e9e4b432d7f773ba3e5b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:12 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-29-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dpll_mgr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index e130c3ed2b6e..e19757c76db6 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -856,7 +856,11 @@ static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv, I915_WRITE(regs[pll->id].ctl, I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE); - if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5)) + if (intel_wait_for_register(dev_priv, + DPLL_STATUS, + DPLL_LOCK(pll->id), + DPLL_LOCK(pll->id), + 5)) DRM_ERROR("DPLL %d not locked\n", pll->id); } -- cgit v1.2.3 From 9b6a2d72d98ce0846c71055c21c407b7f1e668f1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:13 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-30-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 63b720061bd2..146d8329369e 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -90,7 +90,9 @@ static void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port) mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY | LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY; - if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & mask) == mask, 100)) + if (intel_wait_for_register(dev_priv, + MIPI_GEN_FIFO_STAT(port), mask, mask, + 100)) DRM_ERROR("DPI FIFOs are not empty\n"); } -- cgit v1.2.3 From 8c6cea0bb0aa7545f2961a5e1bffb3d08ac3c52c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:14 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-31-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dsi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 146d8329369e..9bbc1f4276cd 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -160,8 +160,10 @@ static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host, /* note: this is never true for reads */ if (packet.payload_length) { - - if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & data_mask) == 0, 50)) + if (intel_wait_for_register(dev_priv, + MIPI_GEN_FIFO_STAT(port), + data_mask, 0, + 50)) DRM_ERROR("Timeout waiting for HS/LP DATA FIFO !full\n"); write_data(dev_priv, data_reg, packet.payload, -- cgit v1.2.3 From 84c2aa9025e7046d25daaa8219cfd36e3f2d7a2d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:15 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-32-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dsi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 9bbc1f4276cd..448d6dcc1529 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -174,7 +174,10 @@ static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host, I915_WRITE(MIPI_INTR_STAT(port), GEN_READ_DATA_AVAIL); } - if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(port)) & ctrl_mask) == 0, 50)) { + if (intel_wait_for_register(dev_priv, + MIPI_GEN_FIFO_STAT(port), + ctrl_mask, 0, + 50)) { DRM_ERROR("Timeout waiting for HS/LP CTRL FIFO !full\n"); } -- cgit v1.2.3 From e7615b3702513821669e81b69a3b459d712f60ba Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:16 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-33-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dsi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 448d6dcc1529..618f849781aa 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -186,7 +186,10 @@ static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host, /* ->rx_len is set only for reads */ if (msg->rx_len) { data_mask = GEN_READ_DATA_AVAIL; - if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & data_mask) == data_mask, 50)) + if (intel_wait_for_register(dev_priv, + MIPI_INTR_STAT(port), + data_mask, data_mask, + 50)) DRM_ERROR("Timeout waiting for read data.\n"); read_data(dev_priv, data_reg, msg->rx_buf, msg->rx_len); -- cgit v1.2.3 From 2af05078d6d9e81fca69de96f582e16e1b141e43 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:17 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-34-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dsi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 618f849781aa..a28dc1845455 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -279,7 +279,9 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs, I915_WRITE(MIPI_DPI_CONTROL(port), cmd); mask = SPL_PKT_SENT_INTERRUPT; - if (wait_for((I915_READ(MIPI_INTR_STAT(port)) & mask) == mask, 100)) + if (intel_wait_for_register(dev_priv, + MIPI_INTR_STAT(port), mask, mask, + 100)) DRM_ERROR("Video mode command 0x%08x send failed.\n", cmd); return 0; -- cgit v1.2.3 From 0698cf6048f65b9bbcf5960364a217af1b81b13b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:18 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-35-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dsi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index a28dc1845455..448741d8653b 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -679,8 +679,9 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) /* Wait till Clock lanes are in LP-00 state for MIPI Port A * only. MIPI Port C has no similar bit for checking */ - if (wait_for(((I915_READ(port_ctrl) & AFE_LATCHOUT) - == 0x00000), 30)) + if (intel_wait_for_register(dev_priv, + port_ctrl, AFE_LATCHOUT, 0, + 30)) DRM_ERROR("DSI LP not going Low\n"); /* Disable MIPI PHY transparent latch */ -- cgit v1.2.3 From 90a392c68c4e1226b65430692ec287511c756520 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:19 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-36-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dsi_pll.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 1765e6e18f2c..cbcc7114c799 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -234,8 +234,11 @@ static void bxt_disable_dsi_pll(struct intel_encoder *encoder) * PLL lock should deassert within 200us. * Wait up to 1ms before timing out. */ - if (wait_for((I915_READ(BXT_DSI_PLL_ENABLE) - & BXT_DSI_PLL_LOCKED) == 0, 1)) + if (intel_wait_for_register(dev_priv, + BXT_DSI_PLL_ENABLE, + BXT_DSI_PLL_LOCKED, + 0, + 1)) DRM_ERROR("Timeout waiting for PLL lock deassertion\n"); } -- cgit v1.2.3 From 186f1c5d8ac197afdf45df431f69c845f5c99478 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:20 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-37-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_dsi_pll.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index cbcc7114c799..4f9930bc89e5 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -489,7 +489,11 @@ static void bxt_enable_dsi_pll(struct intel_encoder *encoder, I915_WRITE(BXT_DSI_PLL_ENABLE, val); /* Timeout and fail if PLL not locked */ - if (wait_for(I915_READ(BXT_DSI_PLL_ENABLE) & BXT_DSI_PLL_LOCKED, 1)) { + if (intel_wait_for_register(dev_priv, + BXT_DSI_PLL_ENABLE, + BXT_DSI_PLL_LOCKED, + BXT_DSI_PLL_LOCKED, + 1)) { DRM_ERROR("Timed out waiting for DSI PLL to lock\n"); return; } -- cgit v1.2.3 From 8d90dfd5ce85457b5bfd8c9d48e967514085f9a5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:21 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-38-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_fbc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 97110533dcaa..978d79532f96 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -124,7 +124,9 @@ static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv) I915_WRITE(FBC_CONTROL, fbc_ctl); /* Wait for compressing bit to clear */ - if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) { + if (intel_wait_for_register(dev_priv, + FBC_STATUS, FBC_STAT_COMPRESSING, 0, + 10)) { DRM_DEBUG_KMS("FBC idle timed out\n"); return; } -- cgit v1.2.3 From 4c802753ba06956f029e61ce478312fbe6880421 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:22 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-39-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_i2c.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 81de23098be7..6bc4c064df0b 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -298,15 +298,16 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv) { int ret; -#define C ((I915_READ_NOTRACE(GMBUS2) & GMBUS_ACTIVE) == 0) - if (!HAS_GMBUS_IRQ(dev_priv)) - return wait_for(C, 10); + return intel_wait_for_register(dev_priv, + GMBUS2, GMBUS_ACTIVE, 0, + 10); /* Important: The hw handles only the first bit, so set only one! */ I915_WRITE(GMBUS4, GMBUS_IDLE_EN); - ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C, + ret = wait_event_timeout(dev_priv->gmbus_wait_queue, + (I915_READ_NOTRACE(GMBUS2) & GMBUS_ACTIVE) == 0, msecs_to_jiffies_timeout(10)); I915_WRITE(GMBUS4, 0); @@ -315,7 +316,6 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv) return 0; else return -ETIMEDOUT; -#undef C } static int -- cgit v1.2.3 From 3e7941a11f7ac83053574e5d246d3e161f2dfa1a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:23 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-40-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 62b0dc6c2642..339d8041075f 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -929,7 +929,10 @@ void intel_logical_ring_stop(struct intel_engine_cs *engine) /* TODO: Is this correct with Execlists enabled? */ I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING)); - if (wait_for((I915_READ_MODE(engine) & MODE_IDLE) != 0, 1000)) { + if (intel_wait_for_register(dev_priv, + RING_MI_MODE(engine->mmio_base), + MODE_IDLE, MODE_IDLE, + 1000)) { DRM_ERROR("%s :timed out trying to stop ring\n", engine->name); return; } -- cgit v1.2.3 From 0d01d0c0099b475677a4d8662d1f48065b993cc5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:24 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-41-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lvds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index cf680661454b..2d141b67503c 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -231,7 +231,7 @@ static void intel_enable_lvds(struct intel_encoder *encoder) I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); POSTING_READ(lvds_encoder->reg); - if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) + if (intel_wait_for_register(dev_priv, stat_reg, PP_ON, PP_ON, 1000)) DRM_ERROR("timed out waiting for panel to power on\n"); intel_panel_enable_backlight(intel_connector); -- cgit v1.2.3 From 7cf41c3d0e5848d9da64c1a5a3514a287bdaaa14 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:25 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-42-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lvds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 2d141b67503c..c26ffef80692 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -253,7 +253,7 @@ static void intel_disable_lvds(struct intel_encoder *encoder) } I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); - if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) + if (intel_wait_for_register(dev_priv, stat_reg, PP_ON, 0, 1000)) DRM_ERROR("timed out waiting for panel to power off\n"); I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN); -- cgit v1.2.3 From eb0241c14ee936ba98d3bdf43506ccb3bef9c21a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:26 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-43-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_psr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 29a09bf6bd18..d299a3d95cfa 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -501,8 +501,11 @@ static void vlv_psr_disable(struct intel_dp *intel_dp) if (dev_priv->psr.active) { /* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */ - if (wait_for((I915_READ(VLV_PSRSTAT(intel_crtc->pipe)) & - VLV_EDP_PSR_IN_TRANS) == 0, 1)) + if (intel_wait_for_register(dev_priv, + VLV_PSRSTAT(intel_crtc->pipe), + VLV_EDP_PSR_IN_TRANS, + 0, + 1)) WARN(1, "PSR transition took longer than expected\n"); val = I915_READ(VLV_PSRCTL(intel_crtc->pipe)); -- cgit v1.2.3 From a5b2fd8cdc576688c65aec82c775fd779d48b503 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:27 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-44-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_psr.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index d299a3d95cfa..bce44ecc9409 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -531,9 +531,11 @@ static void hsw_psr_disable(struct intel_dp *intel_dp) I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE); /* Wait till PSR is idle */ - if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) & - EDP_PSR_STATUS_STATE_MASK) == 0, - 2 * USEC_PER_SEC, 10 * USEC_PER_MSEC)) + if (intel_wait_for_register(dev_priv, + EDP_PSR_STATUS_CTL, + EDP_PSR_STATUS_STATE_MASK, + 0, + 2000)) DRM_ERROR("Timed out waiting for PSR Idle State\n"); dev_priv->psr.active = false; -- cgit v1.2.3 From 12bb63198cb775fe20d5321584059deb70b8b51a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:28 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-45-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_psr.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index bce44ecc9409..8d25c45aa6fe 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -591,14 +591,20 @@ static void intel_psr_work(struct work_struct *work) * and be ready for re-enable. */ if (HAS_DDI(dev_priv)) { - if (wait_for((I915_READ(EDP_PSR_STATUS_CTL) & - EDP_PSR_STATUS_STATE_MASK) == 0, 50)) { + if (intel_wait_for_register(dev_priv, + EDP_PSR_STATUS_CTL, + EDP_PSR_STATUS_STATE_MASK, + 0, + 50)) { DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n"); return; } } else { - if (wait_for((I915_READ(VLV_PSRSTAT(pipe)) & - VLV_EDP_PSR_IN_TRANS) == 0, 1)) { + if (intel_wait_for_register(dev_priv, + VLV_PSRSTAT(pipe), + VLV_EDP_PSR_IN_TRANS, + 0, + 1)) { DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n"); return; } -- cgit v1.2.3 From 25ab57f42f96f7e66af29546bcc67c9057277e84 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:29 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-46-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 04a2d141e690..7ef3e68c8fd6 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -515,8 +515,9 @@ static void intel_ring_setup_status_page(struct intel_engine_cs *engine) I915_WRITE(reg, _MASKED_BIT_ENABLE(INSTPM_TLB_INVALIDATE | INSTPM_SYNC_FLUSH)); - if (wait_for((I915_READ(reg) & INSTPM_SYNC_FLUSH) == 0, - 1000)) + if (intel_wait_for_register(dev_priv, + reg, INSTPM_SYNC_FLUSH, 0, + 1000)) DRM_ERROR("%s: wait for SyncFlush to complete for TLB invalidation timed out\n", engine->name); } -- cgit v1.2.3 From 3d808eb1711f2431fe6ab9f912b2ff795bb74013 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:30 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-47-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7ef3e68c8fd6..05018243aaef 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -529,7 +529,11 @@ static bool stop_ring(struct intel_engine_cs *engine) if (!IS_GEN2(dev_priv)) { I915_WRITE_MODE(engine, _MASKED_BIT_ENABLE(STOP_RING)); - if (wait_for((I915_READ_MODE(engine) & MODE_IDLE) != 0, 1000)) { + if (intel_wait_for_register(dev_priv, + RING_MI_MODE(engine->mmio_base), + MODE_IDLE, + MODE_IDLE, + 1000)) { DRM_ERROR("%s : timed out trying to stop ring\n", engine->name); /* Sometimes we observe that the idle flag is not -- cgit v1.2.3 From d54fe4aad783ef68ffbd5e1bb7b4a33669b1b257 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:31 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-48-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 05018243aaef..c4365cc1f133 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2696,9 +2696,11 @@ static void gen6_bsd_ring_write_tail(struct intel_engine_cs *engine, I915_WRITE64(GEN6_BSD_RNCID, 0x0); /* Wait for the ring not to be idle, i.e. for it to wake up. */ - if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) & - GEN6_BSD_SLEEP_INDICATOR) == 0, - 50)) + if (intel_wait_for_register(dev_priv, + GEN6_BSD_SLEEP_PSMI_CONTROL, + GEN6_BSD_SLEEP_INDICATOR, + 0, + 50)) DRM_ERROR("timed out waiting for the BSD ring to wake up\n"); /* Now that the ring is fully powered up, update the tail */ -- cgit v1.2.3 From 2c2ccc3abc0b1eb16cdc44f1f7430ebe171e4b43 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:32 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-49-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_runtime_pm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 22b46f5f0273..cc8766df8a37 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -365,8 +365,11 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv, if (!is_enabled) { DRM_DEBUG_KMS("Enabling power well\n"); - if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & - HSW_PWR_WELL_STATE_ENABLED), 20)) + if (intel_wait_for_register(dev_priv, + HSW_PWR_WELL_DRIVER, + HSW_PWR_WELL_STATE_ENABLED, + HSW_PWR_WELL_STATE_ENABLED, + 20)) DRM_ERROR("Timeout enabling power well\n"); hsw_power_well_post_enable(dev_priv); } -- cgit v1.2.3 From 117c1148b4b13f67741dd2ca1212520c0cdcfa82 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:33 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-50-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_runtime_pm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index cc8766df8a37..9625d0326d64 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -703,8 +703,11 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, switch (power_well->data) { case SKL_DISP_PW_1: - if (wait_for((I915_READ(SKL_FUSE_STATUS) & - SKL_FUSE_PG0_DIST_STATUS), 1)) { + if (intel_wait_for_register(dev_priv, + SKL_FUSE_STATUS, + SKL_FUSE_PG0_DIST_STATUS, + SKL_FUSE_PG0_DIST_STATUS, + 1)) { DRM_ERROR("PG0 not enabled\n"); return; } -- cgit v1.2.3 From 8b00f55a684a9562146462b92a596b481478de4a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:34 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-51-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_runtime_pm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 9625d0326d64..f212ef31c729 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -768,12 +768,18 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, if (check_fuse_status) { if (power_well->data == SKL_DISP_PW_1) { - if (wait_for((I915_READ(SKL_FUSE_STATUS) & - SKL_FUSE_PG1_DIST_STATUS), 1)) + if (intel_wait_for_register(dev_priv, + SKL_FUSE_STATUS, + SKL_FUSE_PG1_DIST_STATUS, + SKL_FUSE_PG1_DIST_STATUS, + 1)) DRM_ERROR("PG1 distributing status timeout\n"); } else if (power_well->data == SKL_DISP_PW_2) { - if (wait_for((I915_READ(SKL_FUSE_STATUS) & - SKL_FUSE_PG2_DIST_STATUS), 1)) + if (intel_wait_for_register(dev_priv, + SKL_FUSE_STATUS, + SKL_FUSE_PG2_DIST_STATUS, + SKL_FUSE_PG2_DIST_STATUS, + 1)) DRM_ERROR("PG2 distributing status timeout\n"); } } -- cgit v1.2.3 From 919fcd518d438f8ba7518143d76dc834d9d4405c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:35 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-52-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_runtime_pm.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index f212ef31c729..615d0bfaae38 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -1218,7 +1218,6 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv) u32 phy_control = dev_priv->chv_phy_control; u32 phy_status = 0; u32 phy_status_mask = 0xffffffff; - u32 tmp; /* * The BIOS can leave the PHY is some weird state @@ -1306,10 +1305,14 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv) * The PHY may be busy with some initial calibration and whatnot, * so the power state can take a while to actually change. */ - if (wait_for((tmp = I915_READ(DISPLAY_PHY_STATUS) & phy_status_mask) == phy_status, 10)) - WARN(phy_status != tmp, - "Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n", - tmp, phy_status, dev_priv->chv_phy_control); + if (intel_wait_for_register(dev_priv, + DISPLAY_PHY_STATUS, + phy_status_mask, + phy_status, + 10)) + DRM_ERROR("Unexpected PHY_STATUS 0x%08x, expected 0x%08x (PHY_CONTROL=0x%08x)\n", + I915_READ(DISPLAY_PHY_STATUS) & phy_status_mask, + phy_status, dev_priv->chv_phy_control); } #undef BITS_SET -- cgit v1.2.3 From 4ce533b5eb47ed90ede2d798018e036990bcf987 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:37 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-54-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sideband.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index c3998188cf35..56744471cbac 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -51,7 +51,9 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn, WARN_ON(!mutex_is_locked(&dev_priv->sb_lock)); - if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) { + if (intel_wait_for_register(dev_priv, + VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0, + 5)) { DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n", is_read ? "read" : "write"); return -EAGAIN; -- cgit v1.2.3 From dfaa200445ad3494a02581db6bf7ddeead948160 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:38 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-55-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sideband.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 56744471cbac..97893457ddb8 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -64,7 +64,9 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn, I915_WRITE(VLV_IOSF_DATA, *val); I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd); - if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, 5)) { + if (intel_wait_for_register(dev_priv, + VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0, + 5)) { DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n", is_read ? "read" : "write"); return -ETIMEDOUT; -- cgit v1.2.3 From 564514fdde045edb141f2293b0accec673ad1871 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:39 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-56-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sideband.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 97893457ddb8..7dea3c382892 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -206,8 +206,9 @@ u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, u32 value = 0; WARN_ON(!mutex_is_locked(&dev_priv->sb_lock)); - if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, - 100)) { + if (intel_wait_for_register(dev_priv, + SBI_CTL_STAT, SBI_BUSY, 0, + 100)) { DRM_ERROR("timeout waiting for SBI to become ready\n"); return 0; } -- cgit v1.2.3 From 41e8a1e8647a325ce801fbfa9f0f186a4c970a2d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:40 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-57-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sideband.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 7dea3c382892..6841e2315b1b 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -221,8 +221,11 @@ u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg, value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD; I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY); - if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, - 100)) { + if (intel_wait_for_register(dev_priv, + SBI_CTL_STAT, + SBI_BUSY | SBI_RESPONSE_FAIL, + 0, + 100)) { DRM_ERROR("timeout waiting for SBI to complete read transaction\n"); return 0; } -- cgit v1.2.3 From 84a6e1d729ecb8828b22c3c951af5d6d427d3158 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:41 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-58-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sideband.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 6841e2315b1b..11a25ab4d8a2 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -240,8 +240,9 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, WARN_ON(!mutex_is_locked(&dev_priv->sb_lock)); - if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, - 100)) { + if (intel_wait_for_register(dev_priv, + SBI_CTL_STAT, SBI_BUSY, 0, + 100)) { DRM_ERROR("timeout waiting for SBI to become ready\n"); return; } -- cgit v1.2.3 From aaaffb838b6109eed3adc45c2ddebae3c30b4880 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:42 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-59-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_sideband.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c index 11a25ab4d8a2..1a840bf92eea 100644 --- a/drivers/gpu/drm/i915/intel_sideband.c +++ b/drivers/gpu/drm/i915/intel_sideband.c @@ -256,8 +256,11 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value, tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR; I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp); - if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, - 100)) { + if (intel_wait_for_register(dev_priv, + SBI_CTL_STAT, + SBI_BUSY | SBI_RESPONSE_FAIL, + 0, + 100)) { DRM_ERROR("timeout waiting for SBI to complete write transaction\n"); return; } -- cgit v1.2.3 From 87273b7110a031c7b258f8c05efcd88194f79fe8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:43 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-60-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_uncore.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 4c166f6550be..8bc174a2d9e6 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1530,15 +1530,17 @@ static int ironlake_do_reset(struct drm_i915_private *dev_priv, I915_WRITE(ILK_GDSR, ILK_GRDOM_RENDER | ILK_GRDOM_RESET_ENABLE); - ret = wait_for((I915_READ(ILK_GDSR) & - ILK_GRDOM_RESET_ENABLE) == 0, 500); + ret = intel_wait_for_register(dev_priv, + ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0, + 500); if (ret) return ret; I915_WRITE(ILK_GDSR, ILK_GRDOM_MEDIA | ILK_GRDOM_RESET_ENABLE); - ret = wait_for((I915_READ(ILK_GDSR) & - ILK_GRDOM_RESET_ENABLE) == 0, 500); + ret = intel_wait_for_register(dev_priv, + ILK_GDSR, ILK_GRDOM_RESET_ENABLE, 0, + 500); if (ret) return ret; -- cgit v1.2.3 From 76f8421f2a67cdecd616705b7a0c3750d6d42c05 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:45 +0100 Subject: drm/i915: Perform Sandybridge BSD tail write under the forcewake Since we have a sequence of register reads and writes, we can reduce the latency of starting the BSD ring by performing all the mmio operations under the same forcewake wakeref. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-62-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 48d30676455e..485ab1148181 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3882,6 +3882,7 @@ __raw_write(64, q) */ #define I915_READ_FW(reg__) __raw_i915_read32(dev_priv, (reg__)) #define I915_WRITE_FW(reg__, val__) __raw_i915_write32(dev_priv, (reg__), (val__)) +#define I915_WRITE64_FW(reg__, val__) __raw_i915_write64(dev_priv, (reg__), (val__)) #define POSTING_READ_FW(reg__) (void)I915_READ_FW(reg__) /* "Broadcast RGB" property */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c4365cc1f133..7c93d4c210e5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2684,34 +2684,38 @@ static void gen6_bsd_ring_write_tail(struct intel_engine_cs *engine, { struct drm_i915_private *dev_priv = engine->i915; + intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); + /* Every tail move must follow the sequence below */ /* Disable notification that the ring is IDLE. The GT * will then assume that it is busy and bring it out of rc6. */ - I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, - _MASKED_BIT_ENABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); + I915_WRITE_FW(GEN6_BSD_SLEEP_PSMI_CONTROL, + _MASKED_BIT_ENABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); /* Clear the context id. Here be magic! */ - I915_WRITE64(GEN6_BSD_RNCID, 0x0); + I915_WRITE64_FW(GEN6_BSD_RNCID, 0x0); /* Wait for the ring not to be idle, i.e. for it to wake up. */ - if (intel_wait_for_register(dev_priv, - GEN6_BSD_SLEEP_PSMI_CONTROL, - GEN6_BSD_SLEEP_INDICATOR, - 0, - 50)) + if (intel_wait_for_register_fw(dev_priv, + GEN6_BSD_SLEEP_PSMI_CONTROL, + GEN6_BSD_SLEEP_INDICATOR, + 0, + 50)) DRM_ERROR("timed out waiting for the BSD ring to wake up\n"); /* Now that the ring is fully powered up, update the tail */ - I915_WRITE_TAIL(engine, value); - POSTING_READ(RING_TAIL(engine->mmio_base)); + I915_WRITE_FW(RING_TAIL(engine->mmio_base), value); + POSTING_READ_FW(RING_TAIL(engine->mmio_base)); /* Let the ring send IDLE messages to the GT again, * and so let it sleep to conserve power when idle. */ - I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, - _MASKED_BIT_DISABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); + I915_WRITE_FW(GEN6_BSD_SLEEP_PSMI_CONTROL, + _MASKED_BIT_DISABLE(GEN6_BSD_SLEEP_MSG_DISABLE)); + + intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); } static int gen6_bsd_ring_flush(struct drm_i915_gem_request *req, -- cgit v1.2.3 From 4a17fe13c04b4a692ac104ed950c7e9f223b0d3b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:44 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-61-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_uncore.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 8bc174a2d9e6..b49a95a18da4 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1553,20 +1553,16 @@ static int ironlake_do_reset(struct drm_i915_private *dev_priv, static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv, u32 hw_domain_mask) { - int ret; - /* GEN6_GDRST is not in the gt power well, no need to check * for fifo space for the write or forcewake the chip for * the read */ __raw_i915_write32(dev_priv, GEN6_GDRST, hw_domain_mask); -#define ACKED ((__raw_i915_read32(dev_priv, GEN6_GDRST) & hw_domain_mask) == 0) /* Spin waiting for the device to ack the reset requests */ - ret = wait_for(ACKED, 500); -#undef ACKED - - return ret; + return intel_wait_for_register_fw(dev_priv, + GEN6_GDRST, hw_domain_mask, 0, + 500); } /** -- cgit v1.2.3 From ffebb83b34f843aadcbd3e03c4e449da14d0870d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 30 Jun 2016 15:33:36 +0100 Subject: drm/i915: Convert wait_for(I915_READ(reg)) to intel_wait_for_register() By using the out-of-line intel_wait_for_register() not only do we can efficiency from using the hybrid wait_for() contained within, but we avoid code bloat from the numerous inlined loops, in total (all patches): text data bss dec hex filename 1078551 4557 416 1083524 108884 drivers/gpu/drm/i915/i915.ko 1070775 4557 416 1075748 106a24 drivers/gpu/drm/i915/i915.ko Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467297225-21379-53-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_runtime_pm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 615d0bfaae38..7cbba42f0ab4 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -1340,7 +1340,11 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, vlv_set_power_well(dev_priv, power_well, true); /* Poll for phypwrgood signal */ - if (wait_for(I915_READ(DISPLAY_PHY_STATUS) & PHY_POWERGOOD(phy), 1)) + if (intel_wait_for_register(dev_priv, + DISPLAY_PHY_STATUS, + PHY_POWERGOOD(phy), + PHY_POWERGOOD(phy), + 1)) DRM_ERROR("Display PHY %d is not power up\n", phy); mutex_lock(&dev_priv->sb_lock); -- cgit v1.2.3 From 06a2fe22796d9497a35778acc0becb073b242e35 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:20 +0100 Subject: drm/i915: Consolidate write_tail vfunc initializer Introduce a function which initializes vfuncs mostly common across engines and move write_tail initialization in it since only one engine overrides the default. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7c93d4c210e5..f2f78618abb4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2884,6 +2884,12 @@ static int gen6_ring_flush(struct drm_i915_gem_request *req, return 0; } +static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, + struct intel_engine_cs *engine) +{ + engine->write_tail = ring_write_tail; +} + int intel_init_render_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -2897,6 +2903,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->hw_id = 0; engine->mmio_base = RENDER_RING_BASE; + intel_ring_default_vfuncs(dev_priv, engine); + if (INTEL_GEN(dev_priv) >= 8) { if (i915_semaphore_is_enabled(dev_priv)) { obj = i915_gem_object_create(dev, 4096); @@ -2988,7 +2996,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) } engine->irq_enable_mask = I915_USER_INTERRUPT; } - engine->write_tail = ring_write_tail; if (IS_HASWELL(dev_priv)) engine->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; @@ -3047,7 +3054,8 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) engine->exec_id = I915_EXEC_BSD; engine->hw_id = 1; - engine->write_tail = ring_write_tail; + intel_ring_default_vfuncs(dev_priv, engine); + if (INTEL_GEN(dev_priv) >= 6) { engine->mmio_base = GEN6_BSD_RING_BASE; /* gen6 bsd needs a special wa for tail updates */ @@ -3125,9 +3133,10 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) engine->id = VCS2; engine->exec_id = I915_EXEC_BSD; engine->hw_id = 4; - - engine->write_tail = ring_write_tail; engine->mmio_base = GEN8_BSD2_RING_BASE; + + intel_ring_default_vfuncs(dev_priv, engine); + engine->flush = gen6_bsd_ring_flush; engine->add_request = gen6_add_request; engine->irq_seqno_barrier = gen6_seqno_barrier; @@ -3158,9 +3167,10 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) engine->id = BCS; engine->exec_id = I915_EXEC_BLT; engine->hw_id = 2; - engine->mmio_base = BLT_RING_BASE; - engine->write_tail = ring_write_tail; + + intel_ring_default_vfuncs(dev_priv, engine); + engine->flush = gen6_ring_flush; engine->add_request = gen6_add_request; engine->irq_seqno_barrier = gen6_seqno_barrier; @@ -3218,9 +3228,10 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) engine->id = VECS; engine->exec_id = I915_EXEC_VEBOX; engine->hw_id = 3; - engine->mmio_base = VEBOX_RING_BASE; - engine->write_tail = ring_write_tail; + + intel_ring_default_vfuncs(dev_priv, engine); + engine->flush = gen6_ring_flush; engine->add_request = gen6_add_request; engine->irq_seqno_barrier = gen6_seqno_barrier; -- cgit v1.2.3 From 7445a2a41362a570f25354ab1f9b6c23d13b30d3 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:21 +0100 Subject: drm/i915: Consolidate add_request vfunc All engines apart from render select this based on Gen. Move it to the common helper as well. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f2f78618abb4..0e9ab324e35d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2888,6 +2888,11 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { engine->write_tail = ring_write_tail; + + if (INTEL_GEN(dev_priv) >= 6) + engine->add_request = gen6_add_request; + else + engine->add_request = i9xx_add_request; } int intel_init_render_ring_buffer(struct drm_device *dev) @@ -2939,7 +2944,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) } } else if (INTEL_GEN(dev_priv) >= 6) { engine->init_context = intel_rcs_ctx_init; - engine->add_request = gen6_add_request; engine->flush = gen7_render_ring_flush; if (IS_GEN6(dev_priv)) engine->flush = gen6_render_ring_flush; @@ -2980,7 +2984,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT; } else { - engine->add_request = i9xx_add_request; if (INTEL_GEN(dev_priv) < 4) engine->flush = gen2_render_ring_flush; else @@ -3062,7 +3065,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) if (IS_GEN6(dev_priv)) engine->write_tail = gen6_bsd_ring_write_tail; engine->flush = gen6_bsd_ring_flush; - engine->add_request = gen6_add_request; engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; @@ -3102,7 +3104,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) } else { engine->mmio_base = BSD_RING_BASE; engine->flush = bsd_ring_flush; - engine->add_request = i9xx_add_request; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; if (IS_GEN5(dev_priv)) { @@ -3138,7 +3139,6 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_bsd_ring_flush; - engine->add_request = gen6_add_request; engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; @@ -3172,7 +3172,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_ring_flush; - engine->add_request = gen6_add_request; engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; @@ -3233,7 +3232,6 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_ring_flush; - engine->add_request = gen6_add_request; engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; -- cgit v1.2.3 From cc54a828300869528cc8993b4897389fa542cb00 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:22 +0100 Subject: drm/i915: Consolidate seqno_barrier vfunc Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 0e9ab324e35d..98a5ac4aaaa9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2889,10 +2889,12 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, { engine->write_tail = ring_write_tail; - if (INTEL_GEN(dev_priv) >= 6) + if (INTEL_GEN(dev_priv) >= 6) { engine->add_request = gen6_add_request; - else + engine->irq_seqno_barrier = gen6_seqno_barrier; + } else { engine->add_request = i9xx_add_request; + } } int intel_init_render_ring_buffer(struct drm_device *dev) @@ -2950,7 +2952,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->irq_get = gen6_ring_get_irq; engine->irq_put = gen6_ring_put_irq; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; - engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; if (i915_semaphore_is_enabled(dev_priv)) { @@ -3065,7 +3066,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) if (IS_GEN6(dev_priv)) engine->write_tail = gen6_bsd_ring_write_tail; engine->flush = gen6_bsd_ring_flush; - engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; if (INTEL_GEN(dev_priv) >= 8) { @@ -3139,7 +3139,6 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_bsd_ring_flush; - engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; engine->irq_enable_mask = @@ -3172,7 +3171,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_ring_flush; - engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; if (INTEL_GEN(dev_priv) >= 8) { @@ -3232,7 +3230,6 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_ring_flush; - engine->irq_seqno_barrier = gen6_seqno_barrier; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; -- cgit v1.2.3 From b9700325cb0203d3cbe44d25169d7aa195c1f28d Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:23 +0100 Subject: drm/i915: Consolidate get and put irq vfuncs v2: Consistent INTEL_GEN vs IS_GEN usage. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 46 ++++++++++++--------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 98a5ac4aaaa9..72fdf2fc5ff4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2895,6 +2895,23 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, } else { engine->add_request = i9xx_add_request; } + + if (INTEL_GEN(dev_priv) >= 8) { + engine->irq_get = gen8_ring_get_irq; + engine->irq_put = gen8_ring_put_irq; + } else if (INTEL_GEN(dev_priv) >= 6) { + engine->irq_get = gen6_ring_get_irq; + engine->irq_put = gen6_ring_put_irq; + } else if (INTEL_GEN(dev_priv) >= 5) { + engine->irq_get = gen5_ring_get_irq; + engine->irq_put = gen5_ring_put_irq; + } else if (INTEL_GEN(dev_priv) >= 3) { + engine->irq_get = i9xx_ring_get_irq; + engine->irq_put = i9xx_ring_put_irq; + } else { + engine->irq_get = i8xx_ring_get_irq; + engine->irq_put = i8xx_ring_put_irq; + } } int intel_init_render_ring_buffer(struct drm_device *dev) @@ -2933,8 +2950,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->init_context = intel_rcs_ctx_init; engine->add_request = gen8_render_add_request; engine->flush = gen8_render_ring_flush; - engine->irq_get = gen8_ring_get_irq; - engine->irq_put = gen8_ring_put_irq; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; @@ -2949,8 +2964,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->flush = gen7_render_ring_flush; if (IS_GEN6(dev_priv)) engine->flush = gen6_render_ring_flush; - engine->irq_get = gen6_ring_get_irq; - engine->irq_put = gen6_ring_put_irq; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; @@ -2980,8 +2993,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->flush = gen4_render_ring_flush; engine->get_seqno = pc_render_get_seqno; engine->set_seqno = pc_render_set_seqno; - engine->irq_get = gen5_ring_get_irq; - engine->irq_put = gen5_ring_put_irq; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT; } else { @@ -2991,13 +3002,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->flush = gen4_render_ring_flush; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; - if (IS_GEN2(dev_priv)) { - engine->irq_get = i8xx_ring_get_irq; - engine->irq_put = i8xx_ring_put_irq; - } else { - engine->irq_get = i9xx_ring_get_irq; - engine->irq_put = i9xx_ring_put_irq; - } engine->irq_enable_mask = I915_USER_INTERRUPT; } @@ -3071,8 +3075,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; - engine->irq_get = gen8_ring_get_irq; - engine->irq_put = gen8_ring_put_irq; engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { @@ -3082,8 +3084,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) } } else { engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; - engine->irq_get = gen6_ring_get_irq; - engine->irq_put = gen6_ring_put_irq; engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { @@ -3108,12 +3108,8 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) engine->set_seqno = ring_set_seqno; if (IS_GEN5(dev_priv)) { engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT; - engine->irq_get = gen5_ring_get_irq; - engine->irq_put = gen5_ring_put_irq; } else { engine->irq_enable_mask = I915_BSD_USER_INTERRUPT; - engine->irq_get = i9xx_ring_get_irq; - engine->irq_put = i9xx_ring_put_irq; } engine->dispatch_execbuffer = i965_dispatch_execbuffer; } @@ -3143,8 +3139,6 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) engine->set_seqno = ring_set_seqno; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; - engine->irq_get = gen8_ring_get_irq; - engine->irq_put = gen8_ring_put_irq; engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { @@ -3176,8 +3170,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; - engine->irq_get = gen8_ring_get_irq; - engine->irq_put = gen8_ring_put_irq; engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen8_ring_sync; @@ -3186,8 +3178,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) } } else { engine->irq_enable_mask = GT_BLT_USER_INTERRUPT; - engine->irq_get = gen6_ring_get_irq; - engine->irq_put = gen6_ring_put_irq; engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.signal = gen6_signal; @@ -3236,8 +3226,6 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; - engine->irq_get = gen8_ring_get_irq; - engine->irq_put = gen8_ring_put_irq; engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen8_ring_sync; -- cgit v1.2.3 From 604096d7785bc4961dab928023ea61bcd09d59c0 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:24 +0100 Subject: drm/i915: Consolidate get/set_seqno Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 72fdf2fc5ff4..5c7d2659af1b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2888,6 +2888,8 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { engine->write_tail = ring_write_tail; + engine->get_seqno = ring_get_seqno; + engine->set_seqno = ring_set_seqno; if (INTEL_GEN(dev_priv) >= 6) { engine->add_request = gen6_add_request; @@ -2951,8 +2953,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->add_request = gen8_render_add_request; engine->flush = gen8_render_ring_flush; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; if (i915_semaphore_is_enabled(dev_priv)) { WARN_ON(!dev_priv->semaphore_obj); engine->semaphore.sync_to = gen8_ring_sync; @@ -2965,8 +2965,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) if (IS_GEN6(dev_priv)) engine->flush = gen6_render_ring_flush; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen6_ring_sync; engine->semaphore.signal = gen6_signal; @@ -3000,8 +2998,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->flush = gen2_render_ring_flush; else engine->flush = gen4_render_ring_flush; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; engine->irq_enable_mask = I915_USER_INTERRUPT; } @@ -3070,8 +3066,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) if (IS_GEN6(dev_priv)) engine->write_tail = gen6_bsd_ring_write_tail; engine->flush = gen6_bsd_ring_flush; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; @@ -3104,8 +3098,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) } else { engine->mmio_base = BSD_RING_BASE; engine->flush = bsd_ring_flush; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; if (IS_GEN5(dev_priv)) { engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT; } else { @@ -3135,8 +3127,6 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_bsd_ring_flush; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; engine->dispatch_execbuffer = @@ -3165,8 +3155,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_ring_flush; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; @@ -3220,8 +3208,6 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_ring_flush; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = -- cgit v1.2.3 From 1d8a1337f3c8346447cbf1db6af468df6cf58c76 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:25 +0100 Subject: drm/i915: Consolidate init_hw vfunc Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 5c7d2659af1b..100e26c1d765 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2887,6 +2887,7 @@ static int gen6_ring_flush(struct drm_i915_gem_request *req, static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { + engine->init_hw = init_ring_common; engine->write_tail = ring_write_tail; engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; @@ -3105,7 +3106,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) } engine->dispatch_execbuffer = i965_dispatch_execbuffer; } - engine->init_hw = init_ring_common; return intel_init_ring_buffer(dev, engine); } @@ -3136,7 +3136,6 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) engine->semaphore.signal = gen8_xcs_signal; GEN8_RING_SEMAPHORE_INIT(engine); } - engine->init_hw = init_ring_common; return intel_init_ring_buffer(dev, engine); } @@ -3189,7 +3188,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; } } - engine->init_hw = init_ring_common; return intel_init_ring_buffer(dev, engine); } @@ -3238,7 +3236,6 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; } } - engine->init_hw = init_ring_common; return intel_init_ring_buffer(dev, engine); } -- cgit v1.2.3 From 960ecaad7579a38326bcd071d1be8c085d888ddf Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 17:40:26 +0100 Subject: drm/i915: Consolidate dispatch_execbuffer vfunc v2: Put dispatch_execbuffer before add_request. (Chris Wilson) v3: Fix add_request and irq_seqno_barrier for gen8+. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 100e26c1d765..2b4bf23b01fb 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2892,10 +2892,16 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; - if (INTEL_GEN(dev_priv) >= 6) { + if (INTEL_GEN(dev_priv) >= 8) { + engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; + engine->add_request = gen6_add_request; + engine->irq_seqno_barrier = gen6_seqno_barrier; + } else if (INTEL_GEN(dev_priv) >= 6) { + engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; engine->add_request = gen6_add_request; engine->irq_seqno_barrier = gen6_seqno_barrier; } else { + engine->dispatch_execbuffer = i965_dispatch_execbuffer; engine->add_request = i9xx_add_request; } @@ -3004,15 +3010,9 @@ int intel_init_render_ring_buffer(struct drm_device *dev) if (IS_HASWELL(dev_priv)) engine->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; - else if (IS_GEN8(dev_priv)) - engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; - else if (INTEL_GEN(dev_priv) >= 6) - engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; - else if (INTEL_GEN(dev_priv) >= 4) - engine->dispatch_execbuffer = i965_dispatch_execbuffer; else if (IS_I830(dev_priv) || IS_845G(dev_priv)) engine->dispatch_execbuffer = i830_dispatch_execbuffer; - else + else if (INTEL_GEN(dev_priv) <= 3) engine->dispatch_execbuffer = i915_dispatch_execbuffer; engine->init_hw = init_render_ring; engine->cleanup = render_ring_cleanup; @@ -3070,8 +3070,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; - engine->dispatch_execbuffer = - gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen8_ring_sync; engine->semaphore.signal = gen8_xcs_signal; @@ -3079,8 +3077,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) } } else { engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; - engine->dispatch_execbuffer = - gen6_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen6_ring_sync; engine->semaphore.signal = gen6_signal; @@ -3104,7 +3100,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) } else { engine->irq_enable_mask = I915_BSD_USER_INTERRUPT; } - engine->dispatch_execbuffer = i965_dispatch_execbuffer; } return intel_init_ring_buffer(dev, engine); @@ -3129,8 +3124,6 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) engine->flush = gen6_bsd_ring_flush; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; - engine->dispatch_execbuffer = - gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen8_ring_sync; engine->semaphore.signal = gen8_xcs_signal; @@ -3157,7 +3150,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; - engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen8_ring_sync; engine->semaphore.signal = gen8_xcs_signal; @@ -3165,7 +3157,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) } } else { engine->irq_enable_mask = GT_BLT_USER_INTERRUPT; - engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.signal = gen6_signal; engine->semaphore.sync_to = gen6_ring_sync; @@ -3210,7 +3201,6 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; - engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen8_ring_sync; engine->semaphore.signal = gen8_xcs_signal; @@ -3220,7 +3210,6 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) engine->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; engine->irq_get = hsw_vebox_get_irq; engine->irq_put = hsw_vebox_put_irq; - engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; if (i915_semaphore_is_enabled(dev_priv)) { engine->semaphore.sync_to = gen6_ring_sync; engine->semaphore.signal = gen6_signal; -- cgit v1.2.3 From d9a64610b27af01404cc881850cc4903c51a851d Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:27 +0100 Subject: drm/i915: Consolidate semaphore vfuncs init Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_ringbuffer.c | 48 +++++++++++++-------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2b4bf23b01fb..827d23f321f8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2884,6 +2884,22 @@ static int gen6_ring_flush(struct drm_i915_gem_request *req, return 0; } +static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, + struct intel_engine_cs *engine) +{ + if (!i915_semaphore_is_enabled(dev_priv)) + return; + + if (INTEL_GEN(dev_priv) >= 8) { + engine->semaphore.sync_to = gen8_ring_sync; + engine->semaphore.signal = gen8_xcs_signal; + GEN8_RING_SEMAPHORE_INIT(engine); + } else if (INTEL_GEN(dev_priv) >= 6) { + engine->semaphore.sync_to = gen6_ring_sync; + engine->semaphore.signal = gen6_signal; + } +} + static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { @@ -2921,6 +2937,8 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, engine->irq_get = i8xx_ring_get_irq; engine->irq_put = i8xx_ring_put_irq; } + + intel_ring_init_semaphores(dev_priv, engine); } int intel_init_render_ring_buffer(struct drm_device *dev) @@ -2962,9 +2980,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; if (i915_semaphore_is_enabled(dev_priv)) { WARN_ON(!dev_priv->semaphore_obj); - engine->semaphore.sync_to = gen8_ring_sync; engine->semaphore.signal = gen8_rcs_signal; - GEN8_RING_SEMAPHORE_INIT(engine); } } else if (INTEL_GEN(dev_priv) >= 6) { engine->init_context = intel_rcs_ctx_init; @@ -2973,8 +2989,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->flush = gen6_render_ring_flush; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.sync_to = gen6_ring_sync; - engine->semaphore.signal = gen6_signal; /* * The current semaphore is only applied on pre-gen8 * platform. And there is no VCS2 ring on the pre-gen8 @@ -3070,16 +3084,9 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; - if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.sync_to = gen8_ring_sync; - engine->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT(engine); - } } else { engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.sync_to = gen6_ring_sync; - engine->semaphore.signal = gen6_signal; engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR; engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID; engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB; @@ -3124,11 +3131,6 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) engine->flush = gen6_bsd_ring_flush; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; - if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.sync_to = gen8_ring_sync; - engine->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT(engine); - } return intel_init_ring_buffer(dev, engine); } @@ -3150,16 +3152,9 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; - if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.sync_to = gen8_ring_sync; - engine->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT(engine); - } } else { engine->irq_enable_mask = GT_BLT_USER_INTERRUPT; if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.signal = gen6_signal; - engine->semaphore.sync_to = gen6_ring_sync; /* * The current semaphore is only applied on pre-gen8 * platform. And there is no VCS2 ring on the pre-gen8 @@ -3201,18 +3196,11 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) if (INTEL_GEN(dev_priv) >= 8) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; - if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.sync_to = gen8_ring_sync; - engine->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT(engine); - } } else { engine->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; engine->irq_get = hsw_vebox_get_irq; engine->irq_put = hsw_vebox_put_irq; if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.sync_to = gen6_ring_sync; - engine->semaphore.signal = gen6_signal; engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER; engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV; engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB; -- cgit v1.2.3 From db3d4019abaa3a52e66a86fc938a8315f8c4200a Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:28 +0100 Subject: drm/i915: Move semaphore object creation into intel_ring_init_semaphores The object needs to be created before semaphores can be initialized on any ring and it makes sense to pull it out to this semaphore dedicated helper. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 45 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 827d23f321f8..0af8bb1c0a68 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2887,6 +2887,30 @@ static int gen6_ring_flush(struct drm_i915_gem_request *req, static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { + struct drm_i915_gem_object *obj; + int ret; + + if (!i915_semaphore_is_enabled(dev_priv)) + return; + + if (INTEL_GEN(dev_priv) >= 8 && !dev_priv->semaphore_obj) { + obj = i915_gem_object_create(dev_priv->dev, 4096); + if (IS_ERR(obj)) { + DRM_ERROR("Failed to allocate semaphore bo. Disabling semaphores\n"); + i915.semaphores = 0; + } else { + i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); + ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_NONBLOCK); + if (ret != 0) { + drm_gem_object_unreference(&obj->base); + DRM_ERROR("Failed to pin semaphore bo. Disabling semaphores\n"); + i915.semaphores = 0; + } else { + dev_priv->semaphore_obj = obj; + } + } + } + if (!i915_semaphore_is_enabled(dev_priv)) return; @@ -2957,31 +2981,12 @@ int intel_init_render_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); if (INTEL_GEN(dev_priv) >= 8) { - if (i915_semaphore_is_enabled(dev_priv)) { - obj = i915_gem_object_create(dev, 4096); - if (IS_ERR(obj)) { - DRM_ERROR("Failed to allocate semaphore bo. Disabling semaphores\n"); - i915.semaphores = 0; - } else { - i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); - ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_NONBLOCK); - if (ret != 0) { - drm_gem_object_unreference(&obj->base); - DRM_ERROR("Failed to pin semaphore bo. Disabling semaphores\n"); - i915.semaphores = 0; - } else - dev_priv->semaphore_obj = obj; - } - } - engine->init_context = intel_rcs_ctx_init; engine->add_request = gen8_render_add_request; engine->flush = gen8_render_ring_flush; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; - if (i915_semaphore_is_enabled(dev_priv)) { - WARN_ON(!dev_priv->semaphore_obj); + if (i915_semaphore_is_enabled(dev_priv)) engine->semaphore.signal = gen8_rcs_signal; - } } else if (INTEL_GEN(dev_priv) >= 6) { engine->init_context = intel_rcs_ctx_init; engine->flush = gen7_render_ring_flush; -- cgit v1.2.3 From 1b9e665064c6fad91f4265743555406f5804dbcb Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:29 +0100 Subject: drm/i915: Compact Gen8 semaphore initialization Replace the macro initializer with a programatic loop which results in smaller code and hopefully just as clear. v2: Rebase. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 16 ++++++++++++++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 12 ------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 0af8bb1c0a68..aef6824b4c75 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2888,7 +2888,7 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { struct drm_i915_gem_object *obj; - int ret; + int ret, i; if (!i915_semaphore_is_enabled(dev_priv)) return; @@ -2915,9 +2915,21 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, return; if (INTEL_GEN(dev_priv) >= 8) { + u64 offset = i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj); + engine->semaphore.sync_to = gen8_ring_sync; engine->semaphore.signal = gen8_xcs_signal; - GEN8_RING_SEMAPHORE_INIT(engine); + + for (i = 0; i < I915_NUM_ENGINES; i++) { + u64 ring_offset; + + if (i != engine->id) + ring_offset = offset + GEN8_SEMAPHORE_OFFSET(engine->id, i); + else + ring_offset = MI_SEMAPHORE_SYNC_INVALID; + + engine->semaphore.signal_ggtt[i] = ring_offset; + } } else if (INTEL_GEN(dev_priv) >= 6) { engine->semaphore.sync_to = gen6_ring_sync; engine->semaphore.signal = gen6_signal; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index b33c876fed20..113d5230a6de 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -62,18 +62,6 @@ struct intel_hw_status_page { (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \ GEN8_SEMAPHORE_OFFSET(from, (__ring)->id)) -#define GEN8_RING_SEMAPHORE_INIT(e) do { \ - if (!dev_priv->semaphore_obj) { \ - break; \ - } \ - (e)->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET((e), RCS); \ - (e)->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET((e), VCS); \ - (e)->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET((e), BCS); \ - (e)->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET((e), VECS); \ - (e)->semaphore.signal_ggtt[VCS2] = GEN8_SIGNAL_OFFSET((e), VCS2); \ - (e)->semaphore.signal_ggtt[(e)->id] = MI_SEMAPHORE_SYNC_INVALID; \ - } while(0) - enum intel_ring_hangcheck_action { HANGCHECK_IDLE = 0, HANGCHECK_WAIT, -- cgit v1.2.3 From c38c651b39a642d5900e9c8122cfc9bff4343538 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:30 +0100 Subject: drm/i915: Compact gen8_ring_sync Store the semaphore offset in a temporary variable to avoid having to get the VMA offset twice. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index aef6824b4c75..6d5e861fe6c1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1547,6 +1547,7 @@ gen8_ring_sync(struct drm_i915_gem_request *waiter_req, { struct intel_engine_cs *waiter = waiter_req->engine; struct drm_i915_private *dev_priv = waiter_req->i915; + u64 offset = GEN8_WAIT_OFFSET(waiter, signaller->id); struct i915_hw_ppgtt *ppgtt; int ret; @@ -1558,10 +1559,8 @@ gen8_ring_sync(struct drm_i915_gem_request *waiter_req, MI_SEMAPHORE_GLOBAL_GTT | MI_SEMAPHORE_SAD_GTE_SDD); intel_ring_emit(waiter, seqno); - intel_ring_emit(waiter, - lower_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id))); - intel_ring_emit(waiter, - upper_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id))); + intel_ring_emit(waiter, lower_32_bits(offset)); + intel_ring_emit(waiter, upper_32_bits(offset)); intel_ring_advance(waiter); /* When the !RCS engines idle waiting upon a semaphore, they lose their -- cgit v1.2.3 From 4b8e38a9ef490d8e7a4225d05aaf4619eb632d82 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:31 +0100 Subject: drm/i915: Consolidate legacy semaphore initialization Replace per-engine initialization with a common half-programatic, half-data driven code for ease of maintenance and compactness. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 110 ++++++++++++++------------------ 1 file changed, 48 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6d5e861fe6c1..2080668d3630 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2932,6 +2932,54 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, } else if (INTEL_GEN(dev_priv) >= 6) { engine->semaphore.sync_to = gen6_ring_sync; engine->semaphore.signal = gen6_signal; + + /* + * The current semaphore is only applied on pre-gen8 + * platform. And there is no VCS2 ring on the pre-gen8 + * platform. So the semaphore between RCS and VCS2 is + * initialized as INVALID. Gen8 will initialize the + * sema between VCS2 and RCS later. + */ + for (i = 0; i < I915_NUM_ENGINES; i++) { + static const struct { + u32 wait_mbox; + i915_reg_t mbox_reg; + } sem_data[I915_NUM_ENGINES][I915_NUM_ENGINES] = { + [RCS] = { + [VCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_RV, .mbox_reg = GEN6_VRSYNC }, + [BCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_RB, .mbox_reg = GEN6_BRSYNC }, + [VECS] = { .wait_mbox = MI_SEMAPHORE_SYNC_RVE, .mbox_reg = GEN6_VERSYNC }, + }, + [VCS] = { + [RCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_VR, .mbox_reg = GEN6_RVSYNC }, + [BCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_VB, .mbox_reg = GEN6_BVSYNC }, + [VECS] = { .wait_mbox = MI_SEMAPHORE_SYNC_VVE, .mbox_reg = GEN6_VEVSYNC }, + }, + [BCS] = { + [RCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_BR, .mbox_reg = GEN6_RBSYNC }, + [VCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_BV, .mbox_reg = GEN6_VBSYNC }, + [VECS] = { .wait_mbox = MI_SEMAPHORE_SYNC_BVE, .mbox_reg = GEN6_VEBSYNC }, + }, + [VECS] = { + [RCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_VER, .mbox_reg = GEN6_RVESYNC }, + [VCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_VEV, .mbox_reg = GEN6_VVESYNC }, + [BCS] = { .wait_mbox = MI_SEMAPHORE_SYNC_VEB, .mbox_reg = GEN6_BVESYNC }, + }, + }; + u32 wait_mbox; + i915_reg_t mbox_reg; + + if (i == engine->id || i == VCS2) { + wait_mbox = MI_SEMAPHORE_SYNC_INVALID; + mbox_reg = GEN6_NOSYNC; + } else { + wait_mbox = sem_data[engine->id][i].wait_mbox; + mbox_reg = sem_data[engine->id][i].mbox_reg; + } + + engine->semaphore.mbox.wait[i] = wait_mbox; + engine->semaphore.mbox.signal[i] = mbox_reg; + } } } @@ -3004,25 +3052,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) if (IS_GEN6(dev_priv)) engine->flush = gen6_render_ring_flush; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; - if (i915_semaphore_is_enabled(dev_priv)) { - /* - * The current semaphore is only applied on pre-gen8 - * platform. And there is no VCS2 ring on the pre-gen8 - * platform. So the semaphore between RCS and VCS2 is - * initialized as INVALID. Gen8 will initialize the - * sema between VCS2 and RCS later. - */ - engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_INVALID; - engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_RV; - engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_RB; - engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_RVE; - engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - engine->semaphore.mbox.signal[RCS] = GEN6_NOSYNC; - engine->semaphore.mbox.signal[VCS] = GEN6_VRSYNC; - engine->semaphore.mbox.signal[BCS] = GEN6_BRSYNC; - engine->semaphore.mbox.signal[VECS] = GEN6_VERSYNC; - engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; - } } else if (IS_GEN5(dev_priv)) { engine->add_request = pc_render_add_request; engine->flush = gen4_render_ring_flush; @@ -3102,18 +3131,6 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; } else { engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; - if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VR; - engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_INVALID; - engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VB; - engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_VVE; - engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - engine->semaphore.mbox.signal[RCS] = GEN6_RVSYNC; - engine->semaphore.mbox.signal[VCS] = GEN6_NOSYNC; - engine->semaphore.mbox.signal[BCS] = GEN6_BVSYNC; - engine->semaphore.mbox.signal[VECS] = GEN6_VEVSYNC; - engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; - } } } else { engine->mmio_base = BSD_RING_BASE; @@ -3170,25 +3187,6 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; } else { engine->irq_enable_mask = GT_BLT_USER_INTERRUPT; - if (i915_semaphore_is_enabled(dev_priv)) { - /* - * The current semaphore is only applied on pre-gen8 - * platform. And there is no VCS2 ring on the pre-gen8 - * platform. So the semaphore between BCS and VCS2 is - * initialized as INVALID. Gen8 will initialize the - * sema between BCS and VCS2 later. - */ - engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_BR; - engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_BV; - engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_INVALID; - engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_BVE; - engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - engine->semaphore.mbox.signal[RCS] = GEN6_RBSYNC; - engine->semaphore.mbox.signal[VCS] = GEN6_VBSYNC; - engine->semaphore.mbox.signal[BCS] = GEN6_NOSYNC; - engine->semaphore.mbox.signal[VECS] = GEN6_VEBSYNC; - engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; - } } return intel_init_ring_buffer(dev, engine); @@ -3216,18 +3214,6 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) engine->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; engine->irq_get = hsw_vebox_get_irq; engine->irq_put = hsw_vebox_put_irq; - if (i915_semaphore_is_enabled(dev_priv)) { - engine->semaphore.mbox.wait[RCS] = MI_SEMAPHORE_SYNC_VER; - engine->semaphore.mbox.wait[VCS] = MI_SEMAPHORE_SYNC_VEV; - engine->semaphore.mbox.wait[BCS] = MI_SEMAPHORE_SYNC_VEB; - engine->semaphore.mbox.wait[VECS] = MI_SEMAPHORE_SYNC_INVALID; - engine->semaphore.mbox.wait[VCS2] = MI_SEMAPHORE_SYNC_INVALID; - engine->semaphore.mbox.signal[RCS] = GEN6_RVESYNC; - engine->semaphore.mbox.signal[VCS] = GEN6_VVESYNC; - engine->semaphore.mbox.signal[BCS] = GEN6_BVESYNC; - engine->semaphore.mbox.signal[VECS] = GEN6_NOSYNC; - engine->semaphore.mbox.signal[VCS2] = GEN6_NOSYNC; - } } return intel_init_ring_buffer(dev, engine); -- cgit v1.2.3 From 8d228911ffc08bfaa8224d160df8ca64e9dc8274 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 29 Jun 2016 16:09:32 +0100 Subject: drm/i915: Trim some if-else braces Just a bit of cleanup after the previous refactoring. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467212972-861-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_ringbuffer.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2080668d3630..4d61ea923154 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -3126,20 +3126,18 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) if (IS_GEN6(dev_priv)) engine->write_tail = gen6_bsd_ring_write_tail; engine->flush = gen6_bsd_ring_flush; - if (INTEL_GEN(dev_priv) >= 8) { + if (INTEL_GEN(dev_priv) >= 8) engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; - } else { + else engine->irq_enable_mask = GT_BSD_USER_INTERRUPT; - } } else { engine->mmio_base = BSD_RING_BASE; engine->flush = bsd_ring_flush; - if (IS_GEN5(dev_priv)) { + if (IS_GEN5(dev_priv)) engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT; - } else { + else engine->irq_enable_mask = I915_BSD_USER_INTERRUPT; - } } return intel_init_ring_buffer(dev, engine); @@ -3182,12 +3180,11 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->flush = gen6_ring_flush; - if (INTEL_GEN(dev_priv) >= 8) { + if (INTEL_GEN(dev_priv) >= 8) engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; - } else { + else engine->irq_enable_mask = GT_BLT_USER_INTERRUPT; - } return intel_init_ring_buffer(dev, engine); } -- cgit v1.2.3 From 6f7bef75d10e04ad62c0264614df4e013e5e4b67 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 09:18:12 +0100 Subject: drm/i915/ringbuffer: Move all generic engine->dispatch_batchbuffer together Consolidate the block of default vfuncs for dispatching the batchbuffer. Just a minor tweak on top of Tvrtko's great job of tidying up the vfunc initialisation. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467361093-20209-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_ringbuffer.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4d61ea923154..caebe812d10f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2991,25 +2991,29 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, engine->get_seqno = ring_get_seqno; engine->set_seqno = ring_set_seqno; - if (INTEL_GEN(dev_priv) >= 8) { - engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; + engine->add_request = i9xx_add_request; + if (INTEL_GEN(dev_priv) >= 6) engine->add_request = gen6_add_request; - engine->irq_seqno_barrier = gen6_seqno_barrier; - } else if (INTEL_GEN(dev_priv) >= 6) { + + if (INTEL_GEN(dev_priv) >= 8) + engine->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; + else if (INTEL_GEN(dev_priv) >= 6) engine->dispatch_execbuffer = gen6_ring_dispatch_execbuffer; - engine->add_request = gen6_add_request; - engine->irq_seqno_barrier = gen6_seqno_barrier; - } else { + else if (INTEL_GEN(dev_priv) >= 4) engine->dispatch_execbuffer = i965_dispatch_execbuffer; - engine->add_request = i9xx_add_request; - } + else if (IS_I830(dev_priv) || IS_845G(dev_priv)) + engine->dispatch_execbuffer = i830_dispatch_execbuffer; + else + engine->dispatch_execbuffer = i915_dispatch_execbuffer; if (INTEL_GEN(dev_priv) >= 8) { engine->irq_get = gen8_ring_get_irq; engine->irq_put = gen8_ring_put_irq; + engine->irq_seqno_barrier = gen6_seqno_barrier; } else if (INTEL_GEN(dev_priv) >= 6) { engine->irq_get = gen6_ring_get_irq; engine->irq_put = gen6_ring_put_irq; + engine->irq_seqno_barrier = gen6_seqno_barrier; } else if (INTEL_GEN(dev_priv) >= 5) { engine->irq_get = gen5_ring_get_irq; engine->irq_put = gen5_ring_put_irq; @@ -3069,10 +3073,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) if (IS_HASWELL(dev_priv)) engine->dispatch_execbuffer = hsw_ring_dispatch_execbuffer; - else if (IS_I830(dev_priv) || IS_845G(dev_priv)) - engine->dispatch_execbuffer = i830_dispatch_execbuffer; - else if (INTEL_GEN(dev_priv) <= 3) - engine->dispatch_execbuffer = i915_dispatch_execbuffer; + engine->init_hw = init_render_ring; engine->cleanup = render_ring_cleanup; -- cgit v1.2.3 From ed00307893df2a8386307aba36e4a552b72ffb89 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 09:18:13 +0100 Subject: drm/i915/ringbuffer: Move all default irq vfuncs init to a separate func Just plonk all the default irq vfuncs together in one function to keep the initialisers of reasonable size. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467361093-20209-2-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_ringbuffer.c | 43 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index caebe812d10f..24cdc920f4b4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2983,6 +2983,29 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, } } +static void intel_ring_init_irq(struct drm_i915_private *dev_priv, + struct intel_engine_cs *engine) +{ + if (INTEL_GEN(dev_priv) >= 8) { + engine->irq_get = gen8_ring_get_irq; + engine->irq_put = gen8_ring_put_irq; + engine->irq_seqno_barrier = gen6_seqno_barrier; + } else if (INTEL_GEN(dev_priv) >= 6) { + engine->irq_get = gen6_ring_get_irq; + engine->irq_put = gen6_ring_put_irq; + engine->irq_seqno_barrier = gen6_seqno_barrier; + } else if (INTEL_GEN(dev_priv) >= 5) { + engine->irq_get = gen5_ring_get_irq; + engine->irq_put = gen5_ring_put_irq; + } else if (INTEL_GEN(dev_priv) >= 3) { + engine->irq_get = i9xx_ring_get_irq; + engine->irq_put = i9xx_ring_put_irq; + } else { + engine->irq_get = i8xx_ring_get_irq; + engine->irq_put = i8xx_ring_put_irq; + } +} + static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { @@ -3006,25 +3029,7 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, else engine->dispatch_execbuffer = i915_dispatch_execbuffer; - if (INTEL_GEN(dev_priv) >= 8) { - engine->irq_get = gen8_ring_get_irq; - engine->irq_put = gen8_ring_put_irq; - engine->irq_seqno_barrier = gen6_seqno_barrier; - } else if (INTEL_GEN(dev_priv) >= 6) { - engine->irq_get = gen6_ring_get_irq; - engine->irq_put = gen6_ring_put_irq; - engine->irq_seqno_barrier = gen6_seqno_barrier; - } else if (INTEL_GEN(dev_priv) >= 5) { - engine->irq_get = gen5_ring_get_irq; - engine->irq_put = gen5_ring_put_irq; - } else if (INTEL_GEN(dev_priv) >= 3) { - engine->irq_get = i9xx_ring_get_irq; - engine->irq_put = i9xx_ring_put_irq; - } else { - engine->irq_get = i8xx_ring_get_irq; - engine->irq_put = i8xx_ring_put_irq; - } - + intel_ring_init_irq(dev_priv, engine); intel_ring_init_semaphores(dev_priv, engine); } -- cgit v1.2.3 From b99d49ccd9ef15c4096297644c2221c76efbe8b0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Jun 2016 19:13:54 +0300 Subject: drm/i915: Fix log type for RC6 debug messages RC6 isn't really a KMS feature, so use the more proper DRIVER log type for RC6 related debug messages. CC: Sagar Arun Kamble Signed-off-by: Imre Deak Reviewed-by: Sagar Arun Kamble Link: http://patchwork.freedesktop.org/patch/msgid/1467216835-1086-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 870085ab5423..b09fc5f2c792 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4973,14 +4973,15 @@ static void intel_print_rc6_info(struct drm_i915_private *dev_priv, u32 mode) mode = 0; } if (HAS_RC6p(dev_priv)) - DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s RC6p %s RC6pp %s\n", - onoff(mode & GEN6_RC_CTL_RC6_ENABLE), - onoff(mode & GEN6_RC_CTL_RC6p_ENABLE), - onoff(mode & GEN6_RC_CTL_RC6pp_ENABLE)); + DRM_DEBUG_DRIVER("Enabling RC6 states: " + "RC6 %s RC6p %s RC6pp %s\n", + onoff(mode & GEN6_RC_CTL_RC6_ENABLE), + onoff(mode & GEN6_RC_CTL_RC6p_ENABLE), + onoff(mode & GEN6_RC_CTL_RC6pp_ENABLE)); else - DRM_DEBUG_KMS("Enabling RC6 states: RC6 %s\n", - onoff(mode & GEN6_RC_CTL_RC6_ENABLE)); + DRM_DEBUG_DRIVER("Enabling RC6 states: RC6 %s\n", + onoff(mode & GEN6_RC_CTL_RC6_ENABLE)); } static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv) @@ -4990,7 +4991,7 @@ static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv) unsigned long rc6_ctx_base; if (!(I915_READ(RC6_LOCATION) & RC6_CTX_IN_DRAM)) { - DRM_DEBUG_KMS("RC6 Base location not set properly.\n"); + DRM_DEBUG_DRIVER("RC6 Base location not set properly.\n"); enable_rc6 = false; } @@ -5002,7 +5003,7 @@ static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv) if (!((rc6_ctx_base >= ggtt->stolen_reserved_base) && (rc6_ctx_base + PAGE_SIZE <= ggtt->stolen_reserved_base + ggtt->stolen_reserved_size))) { - DRM_DEBUG_KMS("RC6 Base address not as expected.\n"); + DRM_DEBUG_DRIVER("RC6 Base address not as expected.\n"); enable_rc6 = false; } @@ -5010,7 +5011,7 @@ static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv) ((I915_READ(PWRCTX_MAXCNT_VCSUNIT0) & IDLE_TIME_MASK) > 1) && ((I915_READ(PWRCTX_MAXCNT_BCSUNIT) & IDLE_TIME_MASK) > 1) && ((I915_READ(PWRCTX_MAXCNT_VECSUNIT) & IDLE_TIME_MASK) > 1))) { - DRM_DEBUG_KMS("Engine Idle wait time not set properly.\n"); + DRM_DEBUG_DRIVER("Engine Idle wait time not set properly.\n"); enable_rc6 = false; } @@ -5018,7 +5019,7 @@ static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv) GEN6_RC_CTL_HW_ENABLE)) && ((I915_READ(GEN6_RC_CONTROL) & GEN6_RC_CTL_HW_ENABLE) || !(I915_READ(GEN6_RC_STATE) & RC6_STATE))) { - DRM_DEBUG_KMS("HW/SW RC6 is not enabled by BIOS.\n"); + DRM_DEBUG_DRIVER("HW/SW RC6 is not enabled by BIOS.\n"); enable_rc6 = false; } @@ -5050,8 +5051,9 @@ int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6) mask = INTEL_RC6_ENABLE; if ((enable_rc6 & mask) != enable_rc6) - DRM_DEBUG_KMS("Adjusting RC6 mask to %d (requested %d, valid %d)\n", - enable_rc6 & mask, enable_rc6, mask); + DRM_DEBUG_DRIVER("Adjusting RC6 mask to %d " + "(requested %d, valid %d)\n", + enable_rc6 & mask, enable_rc6, mask); return enable_rc6 & mask; } -- cgit v1.2.3 From fc6198417264e757ab11a6198c1afb6f46976a47 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 29 Jun 2016 19:13:55 +0300 Subject: drm/i915/bxt: Fix sanity check for BIOS RC6 setup BXT BIOS has two options related to GPU power management: "RC6(Render Standby)" and "GT PM Support". The assumption so far was that disabling either of these options would leave RC6 uninitialized. According to my tests this isn't so: for a proper RC6 setup we only need the "GT PM Support" option to be enabled while the "RC6" option only controls whether RC6 is left enabled or not by BIOS. OTOH we were missing a few checks to ensure a proper RC6 setup. Add these now and don't fail the sanity check if RC6 is disabled. This fixes a problem where RC6 remains disabled after reloading the driver, since we explicitly disable RC6 during unloading. v2: - Print a debug message about the BIOS enabled RC state. (Sagar) CC: Sagar Arun Kamble Signed-off-by: Imre Deak Reviewed-by: Sagar Arun Kamble Link: http://patchwork.freedesktop.org/patch/msgid/1467216835-1086-2-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 7 ++++++- drivers/gpu/drm/i915/intel_pm.c | 30 +++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c6bfbf8d7cca..8bfde75789f6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7070,7 +7070,8 @@ enum { #define GEN6_RPDEUC _MMIO(0xA084) #define GEN6_RPDEUCSW _MMIO(0xA088) #define GEN6_RC_STATE _MMIO(0xA094) -#define RC6_STATE (1 << 18) +#define RC_SW_TARGET_STATE_SHIFT 16 +#define RC_SW_TARGET_STATE_MASK (7 << RC_SW_TARGET_STATE_SHIFT) #define GEN6_RC1_WAKE_RATE_LIMIT _MMIO(0xA098) #define GEN6_RC6_WAKE_RATE_LIMIT _MMIO(0xA09C) #define GEN6_RC6pp_WAKE_RATE_LIMIT _MMIO(0xA0A0) @@ -7085,12 +7086,16 @@ enum { #define GEN6_RC6pp_THRESHOLD _MMIO(0xA0C0) #define GEN6_PMINTRMSK _MMIO(0xA168) #define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31) +#define GEN8_MISC_CTRL0 _MMIO(0xA180) #define VLV_PWRDWNUPCTL _MMIO(0xA294) #define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4) #define GEN9_RENDER_PG_IDLE_HYSTERESIS _MMIO(0xA0C8) #define GEN9_PG_ENABLE _MMIO(0xA210) #define GEN9_RENDER_PG_ENABLE (1<<0) #define GEN9_MEDIA_PG_ENABLE (1<<1) +#define GEN8_PUSHBUS_CONTROL _MMIO(0xA248) +#define GEN8_PUSHBUS_ENABLE _MMIO(0xA250) +#define GEN8_PUSHBUS_SHIFT _MMIO(0xA25C) #define VLV_CHICKEN_3 _MMIO(VLV_DISPLAY_BASE + 0x7040C) #define PIXEL_OVERLAP_CNT_MASK (3 << 30) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b09fc5f2c792..cfe850f8815a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4989,6 +4989,17 @@ static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv) struct i915_ggtt *ggtt = &dev_priv->ggtt; bool enable_rc6 = true; unsigned long rc6_ctx_base; + u32 rc_ctl; + int rc_sw_target; + + rc_ctl = I915_READ(GEN6_RC_CONTROL); + rc_sw_target = (I915_READ(GEN6_RC_STATE) & RC_SW_TARGET_STATE_MASK) >> + RC_SW_TARGET_STATE_SHIFT; + DRM_DEBUG_DRIVER("BIOS enabled RC states: " + "HW_CTRL %s HW_RC6 %s SW_TARGET_STATE %x\n", + onoff(rc_ctl & GEN6_RC_CTL_HW_ENABLE), + onoff(rc_ctl & GEN6_RC_CTL_RC6_ENABLE), + rc_sw_target); if (!(I915_READ(RC6_LOCATION) & RC6_CTX_IN_DRAM)) { DRM_DEBUG_DRIVER("RC6 Base location not set properly.\n"); @@ -5015,11 +5026,20 @@ static bool bxt_check_bios_rc6_setup(struct drm_i915_private *dev_priv) enable_rc6 = false; } - if (!(I915_READ(GEN6_RC_CONTROL) & (GEN6_RC_CTL_RC6_ENABLE | - GEN6_RC_CTL_HW_ENABLE)) && - ((I915_READ(GEN6_RC_CONTROL) & GEN6_RC_CTL_HW_ENABLE) || - !(I915_READ(GEN6_RC_STATE) & RC6_STATE))) { - DRM_DEBUG_DRIVER("HW/SW RC6 is not enabled by BIOS.\n"); + if (!I915_READ(GEN8_PUSHBUS_CONTROL) || + !I915_READ(GEN8_PUSHBUS_ENABLE) || + !I915_READ(GEN8_PUSHBUS_SHIFT)) { + DRM_DEBUG_DRIVER("Pushbus not setup properly.\n"); + enable_rc6 = false; + } + + if (!I915_READ(GEN6_GFXPAUSE)) { + DRM_DEBUG_DRIVER("GFX pause not setup properly.\n"); + enable_rc6 = false; + } + + if (!I915_READ(GEN8_MISC_CTRL0)) { + DRM_DEBUG_DRIVER("GPM control not setup properly.\n"); enable_rc6 = false; } -- cgit v1.2.3 From 37f501afed23fa1126017255495d5be5e97c9d6d Mon Sep 17 00:00:00 2001 From: "arun.siluvery@linux.intel.com" Date: Fri, 1 Jul 2016 11:43:02 +0100 Subject: drm/i915/bxt: Export pooled eu info to userspace Pooled EU is a bxt only feature and kernel changes are already merged. This feature is not yet exposed to userspace as the support was not yet available. Beignet team expressed interest and added patches to use this. Since we now have a user and patches to use them, expose them from the kernel side as well. v2: fix compile error [1] https://lists.freedesktop.org/archives/beignet/2016-June/007698.html [2] https://lists.freedesktop.org/archives/beignet/2016-June/007699.html Cc: Winiarski, Michal Cc: Zou, Nanhai Cc: Yang, Rong R Cc: Tim Gore Cc: Jeff McGee Signed-off-by: Arun Siluvery Acked-by: Chris Wilson Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467369782-25992-1-git-send-email-arun.siluvery@linux.intel.com Acked-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.c | 6 ++++++ include/uapi/drm/i915_drm.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c580e24095b0..8a2674013aef 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -365,6 +365,12 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_EXEC_SOFTPIN: value = 1; break; + case I915_PARAM_HAS_POOLED_EU: + value = HAS_POOLED_EU(dev); + break; + case I915_PARAM_MIN_EU_IN_POOL: + value = INTEL_INFO(dev)->min_eu_in_pool; + break; default: DRM_DEBUG("Unknown parameter %d\n", param->param); return -EINVAL; diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index c17d63d8b543..a642bbc7777d 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -361,6 +361,8 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_GPU_RESET 35 #define I915_PARAM_HAS_RESOURCE_STREAMER 36 #define I915_PARAM_HAS_EXEC_SOFTPIN 37 +#define I915_PARAM_HAS_POOLED_EU 38 +#define I915_PARAM_MIN_EU_IN_POOL 39 typedef struct drm_i915_getparam { __s32 param; -- cgit v1.2.3 From c73930266d3b060d0ff0832b71caad95ac09b4a6 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 1 Jul 2016 17:40:45 +0300 Subject: drm/i915/bxt: Remove the preliminary_hw_support flag Broxton is now part of CI which doesn't indicate any major problems so enable the driver by default. Signed-off-by: Imre Deak Reviewed-by: Rodrigo Vivi Link: http://patchwork.freedesktop.org/patch/msgid/1467384045-17028-1-git-send-email-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_pci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index a7f8f4fb7e8d..949c01686a66 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -331,7 +331,6 @@ static const struct intel_device_info intel_skylake_gt3_info = { }; static const struct intel_device_info intel_broxton_info = { - .is_preliminary = 1, .is_broxton = 1, .gen = 9, .need_gfx_hws = 1, .has_hotplug = 1, -- cgit v1.2.3 From bed50aea61df4e62395620795079f0e7a3876723 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:10 +0100 Subject: drm/i915/shrinker: Flush active on objects before counting As we inspect obj->active to decide how many objects we can shrink (we only shrink idle objects), it helps to flush the active lists first in order to have a more accurate count of available objects. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_shrinker.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 886a8797566d..1bf14544d8ad 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -265,6 +265,8 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) if (!i915_gem_shrinker_lock(dev, &unlock)) return 0; + i915_gem_retire_requests(dev_priv); + count = 0; list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) if (can_release_pages(obj)) -- cgit v1.2.3 From 05535726d3004d8a4d1444f310ab27b251391a70 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:11 +0100 Subject: drm/i915: Delay queuing hangcheck to wait-request We can forgo queuing the hangcheck from the start of every request to until we wait upon a request. This reduces the overhead of every request, but may increase the latency of detecting a hang. However, if nothing every waits upon a hang, did it ever hang? It also improves the robustness of the wait-request by ensuring that the hangchecker is indeed running before we sleep indefinitely (and thereby ensuring that we never actually sleep forever waiting for a dead GPU). As pointed out by Tvrtko, it is possible for a GPU hang to go unnoticed for as long as nobody is waiting for the GPU. Though this rare, during that time we may be consuming more power than if we had promptly recovered, and in the most extreme case we may exhaust all memory before forcing the hangcheck. Something to be wary off in future. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 15 +++++++++++---- drivers/gpu/drm/i915/i915_irq.c | 10 ++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1d9878258103..e0b1e286bf87 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1532,6 +1532,15 @@ int __i915_wait_request(struct drm_i915_gem_request *req, break; } + /* Ensure that even if the GPU hangs, we get woken up. + * + * However, note that if no one is waiting, we never notice + * a gpu hang. Eventually, we will have to wait for a resource + * held by the GPU and so trigger a hangcheck. In the most + * pathological case, this will be upon memory starvation! + */ + i915_queue_hangcheck(dev_priv); + timer.function = NULL; if (timeout || missed_irq(dev_priv, engine)) { unsigned long expire; @@ -2919,8 +2928,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, /* Not allowed to fail! */ WARN(ret, "emit|add_request failed: %d!\n", ret); - i915_queue_hangcheck(engine->i915); - queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, round_jiffies_up_relative(HZ)); @@ -3264,8 +3271,8 @@ i915_gem_retire_requests(struct drm_i915_private *dev_priv) if (idle) mod_delayed_work(dev_priv->wq, - &dev_priv->mm.idle_work, - msecs_to_jiffies(100)); + &dev_priv->mm.idle_work, + msecs_to_jiffies(100)); return idle; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4378a659d962..5614582ca240 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3135,10 +3135,10 @@ static void i915_hangcheck_elapsed(struct work_struct *work) intel_uncore_arm_unclaimed_mmio_detection(dev_priv); for_each_engine_id(engine, dev_priv, id) { + bool busy = waitqueue_active(&engine->irq_queue); u64 acthd; u32 seqno; unsigned user_interrupts; - bool busy = true; semaphore_clear_deadlocks(dev_priv); @@ -3161,12 +3161,11 @@ static void i915_hangcheck_elapsed(struct work_struct *work) if (engine->hangcheck.seqno == seqno) { if (ring_idle(engine, seqno)) { engine->hangcheck.action = HANGCHECK_IDLE; - if (waitqueue_active(&engine->irq_queue)) { + if (busy) { /* Safeguard against driver failure */ user_interrupts = kick_waiters(engine); engine->hangcheck.score += BUSY; - } else - busy = false; + } } else { /* We always increment the hangcheck score * if the ring is busy and still processing @@ -3240,9 +3239,8 @@ static void i915_hangcheck_elapsed(struct work_struct *work) goto out; } + /* Reset timer in case GPU hangs without another request being added */ if (busy_count) - /* Reset timer case chip hangs without another request - * being added */ i915_queue_hangcheck(dev_priv); out: -- cgit v1.2.3 From 7774002586703aac3952f332bdf14759865171ef Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:12 +0100 Subject: drm/i915: Remove the dedicated hangcheck workqueue The queue only ever contains at most one item and has no special flags. It is just a very simple wrapper around the system-wq - a complication with no benefits. v2: Use the system_long_wq as we may wish to capture the error state after detecting the hang - which may take a bit of time. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-3-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 8 -------- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_irq.c | 7 ++++--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8a2674013aef..c9abf912249f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1175,15 +1175,8 @@ static int i915_workqueues_init(struct drm_i915_private *dev_priv) if (dev_priv->hotplug.dp_wq == NULL) goto out_free_wq; - dev_priv->gpu_error.hangcheck_wq = - alloc_ordered_workqueue("i915-hangcheck", 0); - if (dev_priv->gpu_error.hangcheck_wq == NULL) - goto out_free_dp_wq; - return 0; -out_free_dp_wq: - destroy_workqueue(dev_priv->hotplug.dp_wq); out_free_wq: destroy_workqueue(dev_priv->wq); out_err: @@ -1194,7 +1187,6 @@ out_err: static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) { - destroy_workqueue(dev_priv->gpu_error.hangcheck_wq); destroy_workqueue(dev_priv->hotplug.dp_wq); destroy_workqueue(dev_priv->wq); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 485ab1148181..f4aa727e522a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1374,7 +1374,6 @@ struct i915_gpu_error { /* Hang gpu twice in this window and your context gets banned */ #define DRM_I915_CTX_BAN_PERIOD DIV_ROUND_UP(8*DRM_I915_HANGCHECK_PERIOD, 1000) - struct workqueue_struct *hangcheck_wq; struct delayed_work hangcheck_work; /* For reset and error_state handling. */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5614582ca240..3ad4ef9250d8 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3249,7 +3249,7 @@ out: void i915_queue_hangcheck(struct drm_i915_private *dev_priv) { - struct i915_gpu_error *e = &dev_priv->gpu_error; + unsigned long delay; if (!i915.enable_hangcheck) return; @@ -3259,8 +3259,9 @@ void i915_queue_hangcheck(struct drm_i915_private *dev_priv) * we will ignore a hung ring if a second ring is kept busy. */ - queue_delayed_work(e->hangcheck_wq, &e->hangcheck_work, - round_jiffies_up_relative(DRM_I915_HANGCHECK_JIFFIES)); + delay = round_jiffies_up_relative(DRM_I915_HANGCHECK_JIFFIES); + queue_delayed_work(system_long_wq, + &dev_priv->gpu_error.hangcheck_work, delay); } static void ibx_irq_reset(struct drm_device *dev) -- cgit v1.2.3 From 26a02b8fc35ff2c393505bccd9f046e8d50c1708 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:13 +0100 Subject: drm/i915: Make queueing the hangcheck work inline Since the function is a small wrapper around schedule_delayed_work(), move it inline to remove the function call overhead for the principle caller. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-4-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 18 +++++++++++++++++- drivers/gpu/drm/i915/i915_irq.c | 17 ----------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f4aa727e522a..4948c90c9bd4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2932,7 +2932,23 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); bool intel_hpd_pin_to_port(enum hpd_pin pin, enum port *port); /* i915_irq.c */ -void i915_queue_hangcheck(struct drm_i915_private *dev_priv); +static inline void i915_queue_hangcheck(struct drm_i915_private *dev_priv) +{ + unsigned long delay; + + if (unlikely(!i915.enable_hangcheck)) + return; + + /* Don't continually defer the hangcheck so that it is always run at + * least once after work has been scheduled on any ring. Otherwise, + * we will ignore a hung ring if a second ring is kept busy. + */ + + delay = round_jiffies_up_relative(DRM_I915_HANGCHECK_JIFFIES); + queue_delayed_work(system_long_wq, + &dev_priv->gpu_error.hangcheck_work, delay); +} + __printf(3, 4) void i915_handle_error(struct drm_i915_private *dev_priv, u32 engine_mask, diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 3ad4ef9250d8..83f40baeb1f3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3247,23 +3247,6 @@ out: ENABLE_RPM_WAKEREF_ASSERTS(dev_priv); } -void i915_queue_hangcheck(struct drm_i915_private *dev_priv) -{ - unsigned long delay; - - if (!i915.enable_hangcheck) - return; - - /* Don't continually defer the hangcheck so that it is always run at - * least once after work has been scheduled on any ring. Otherwise, - * we will ignore a hung ring if a second ring is kept busy. - */ - - delay = round_jiffies_up_relative(DRM_I915_HANGCHECK_JIFFIES); - queue_delayed_work(system_long_wq, - &dev_priv->gpu_error.hangcheck_work, delay); -} - static void ibx_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; -- cgit v1.2.3 From 1f15b76f1ec973d1eb5d21b6d98b21aebb9025f1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:14 +0100 Subject: drm/i915: Separate GPU hang waitqueue from advance Currently __i915_wait_request uses a per-engine wait_queue_t for the dual purpose of waking after the GPU advances or for waking after an error. In the future, we may add even more wake sources and require greater separation, but for now we can conceptually simplify wakeups by separating the two sources. In particular, this allows us to use different wait-queues (e.g. one on the engine advancement, a global one for errors and one on each requests) without any hassle. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-5-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ drivers/gpu/drm/i915/i915_gem.c | 5 +++++ drivers/gpu/drm/i915/i915_irq.c | 19 ++++--------------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4948c90c9bd4..0d0e4ac4dadb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1409,6 +1409,12 @@ struct i915_gpu_error { #define I915_RESET_IN_PROGRESS_FLAG 1 #define I915_WEDGED (1 << 31) + /** + * Waitqueue to signal when a hang is detected. Used to for waiters + * to release the struct_mutex for the reset to procede. + */ + wait_queue_head_t wait_queue; + /** * Waitqueue to signal when the reset has completed. Used by clients * that wait for dev_priv->mm.wedged to settle. diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e0b1e286bf87..b5278d117ea0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1455,6 +1455,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, const bool irq_test_in_progress = ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_engine_flag(engine); int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; + DEFINE_WAIT(reset); DEFINE_WAIT(wait); unsigned long timeout_expire; s64 before = 0; /* Only to silence a compiler warning. */ @@ -1499,6 +1500,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, goto out; } + add_wait_queue(&dev_priv->gpu_error.wait_queue, &reset); for (;;) { struct timer_list timer; @@ -1557,6 +1559,8 @@ int __i915_wait_request(struct drm_i915_gem_request *req, destroy_timer_on_stack(&timer); } } + remove_wait_queue(&dev_priv->gpu_error.wait_queue, &reset); + if (!irq_test_in_progress) engine->irq_put(engine); @@ -5287,6 +5291,7 @@ i915_gem_load_init(struct drm_device *dev) i915_gem_retire_work_handler); INIT_DELAYED_WORK(&dev_priv->mm.idle_work, i915_gem_idle_work_handler); + init_waitqueue_head(&dev_priv->gpu_error.wait_queue); init_waitqueue_head(&dev_priv->gpu_error.reset_queue); dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 83f40baeb1f3..6c17596d75dd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2488,11 +2488,8 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) return ret; } -static void i915_error_wake_up(struct drm_i915_private *dev_priv, - bool reset_completed) +static void i915_error_wake_up(struct drm_i915_private *dev_priv) { - struct intel_engine_cs *engine; - /* * Notify all waiters for GPU completion events that reset state has * been changed, and that they need to restart their wait after @@ -2501,18 +2498,10 @@ static void i915_error_wake_up(struct drm_i915_private *dev_priv, */ /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */ - for_each_engine(engine, dev_priv) - wake_up_all(&engine->irq_queue); + wake_up_all(&dev_priv->gpu_error.wait_queue); /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */ wake_up_all(&dev_priv->pending_flip_queue); - - /* - * Signal tasks blocked in i915_gem_wait_for_error that the pending - * reset state is cleared. - */ - if (reset_completed) - wake_up_all(&dev_priv->gpu_error.reset_queue); } /** @@ -2577,7 +2566,7 @@ static void i915_reset_and_wakeup(struct drm_i915_private *dev_priv) * Note: The wake_up also serves as a memory barrier so that * waiters see the update value of the reset counter atomic_t. */ - i915_error_wake_up(dev_priv, true); + wake_up_all(&dev_priv->gpu_error.reset_queue); } } @@ -2714,7 +2703,7 @@ void i915_handle_error(struct drm_i915_private *dev_priv, * ensure that the waiters see the updated value of the reset * counter atomic_t. */ - i915_error_wake_up(dev_priv, false); + i915_error_wake_up(dev_priv); } i915_reset_and_wakeup(dev_priv); -- cgit v1.2.3 From 688e6c7258164de86d626e8e983ca8d28015c263 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:15 +0100 Subject: drm/i915: Slaughter the thundering i915_wait_request herd One particularly stressful scenario consists of many independent tasks all competing for GPU time and waiting upon the results (e.g. realtime transcoding of many, many streams). One bottleneck in particular is that each client waits on its own results, but every client is woken up after every batchbuffer - hence the thunder of hooves as then every client must do its heavyweight dance to read a coherent seqno to see if it is the lucky one. Ideally, we only want one client to wake up after the interrupt and check its request for completion. Since the requests must retire in order, we can select the first client on the oldest request to be woken. Once that client has completed his wait, we can then wake up the next client and so on. However, all clients then incur latency as every process in the chain may be delayed for scheduling - this may also then cause some priority inversion. To reduce the latency, when a client is added or removed from the list, we scan the tree for completed seqno and wake up all the completed waiters in parallel. Using igt/benchmarks/gem_latency, we can demonstrate this effect. The benchmark measures the number of GPU cycles between completion of a batch and the client waking up from a call to wait-ioctl. With many concurrent waiters, with each on a different request, we observe that the wakeup latency before the patch scales nearly linearly with the number of waiters (before external factors kick in making the scaling much worse). After applying the patch, we can see that only the single waiter for the request is being woken up, providing a constant wakeup latency for every operation. However, the situation is not quite as rosy for many waiters on the same request, though to the best of my knowledge this is much less likely in practice. Here, we can observe that the concurrent waiters incur extra latency from being woken up by the solitary bottom-half, rather than directly by the interrupt. This appears to be scheduler induced (having discounted adverse effects from having a rbtree walk/erase in the wakeup path), each additional wake_up_process() costs approximately 1us on big core. Another effect of performing the secondary wakeups from the first bottom-half is the incurred delay this imposes on high priority threads - rather than immediately returning to userspace and leaving the interrupt handler to wake the others. To offset the delay incurred with additional waiters on a request, we could use a hybrid scheme that did a quick read in the interrupt handler and dequeued all the completed waiters (incurring the overhead in the interrupt handler, not the best plan either as we then incur GPU submission latency) but we would still have to wake up the bottom-half every time to do the heavyweight slow read. Or we could only kick the waiters on the seqno with the same priority as the current task (i.e. in the realtime waiter scenario, only it is woken up immediately by the interrupt and simply queues the next waiter before returning to userspace, minimising its delay at the expense of the chain, and also reducing contention on its scheduler runqueue). This is effective at avoid long pauses in the interrupt handler and at avoiding the extra latency in realtime/high-priority waiters. v2: Convert from a kworker per engine into a dedicated kthread for the bottom-half. v3: Rename request members and tweak comments. v4: Use a per-engine spinlock in the breadcrumbs bottom-half. v5: Fix race in locklessly checking waiter status and kicking the task on adding a new waiter. v6: Fix deciding when to force the timer to hide missing interrupts. v7: Move the bottom-half from the kthread to the first client process. v8: Reword a few comments v9: Break the busy loop when the interrupt is unmasked or has fired. v10: Comments, unnecessary churn, better debugging from Tvrtko v11: Wake all completed waiters on removing the current bottom-half to reduce the latency of waking up a herd of clients all waiting on the same request. v12: Rearrange missed-interrupt fault injection so that it works with igt/drv_missed_irq_hang v13: Rename intel_breadcrumb and friends to intel_wait in preparation for signal handling. v14: RCU commentary, assert_spin_locked v15: Hide BUG_ON behind the compiler; report on gem_latency findings. v16: Sort seqno-groups by priority so that first-waiter has the highest task priority (and so avoid priority inversion). v17: Add waiters to post-mortem GPU hang state. v18: Return early for a completed wait after acquiring the spinlock. Avoids adding ourselves to the tree if the is already complete, and skips the awkward question of why we don't do completion wakeups for waits earlier than or equal to ourselves. v19: Prepare for init_breadcrumbs to fail. Later patches may want to allocate during init, so be prepared to propagate back the error code. Testcase: igt/gem_concurrent_blit Testcase: igt/benchmarks/gem_latency Signed-off-by: Chris Wilson Cc: "Rogozhkin, Dmitry V" Cc: "Gong, Zhipeng" Cc: Tvrtko Ursulin Cc: Dave Gordon Cc: "Goel, Akash" Reviewed-by: Tvrtko Ursulin #v18 Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-6-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 16 +- drivers/gpu/drm/i915/i915_drv.h | 40 +++- drivers/gpu/drm/i915/i915_gem.c | 143 +++++------- drivers/gpu/drm/i915/i915_gpu_error.c | 60 ++++- drivers/gpu/drm/i915/i915_irq.c | 20 +- drivers/gpu/drm/i915/intel_breadcrumbs.c | 380 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.c | 7 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 12 +- drivers/gpu/drm/i915/intel_ringbuffer.h | 79 ++++++- 10 files changed, 648 insertions(+), 110 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_breadcrumbs.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index a3d2b789c9ec..618293c8c9d9 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -38,6 +38,7 @@ i915-y += i915_cmd_parser.o \ i915_gem_userptr.o \ i915_gpu_error.o \ i915_trace_points.o \ + intel_breadcrumbs.o \ intel_lrc.o \ intel_mocs.o \ intel_ringbuffer.o \ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f664884ad27f..f522a366223d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -788,10 +788,22 @@ static int i915_gem_request_info(struct seq_file *m, void *data) static void i915_ring_seqno_info(struct seq_file *m, struct intel_engine_cs *engine) { + struct intel_breadcrumbs *b = &engine->breadcrumbs; + struct rb_node *rb; + seq_printf(m, "Current sequence (%s): %x\n", engine->name, engine->get_seqno(engine)); seq_printf(m, "Current user interrupts (%s): %x\n", engine->name, READ_ONCE(engine->user_interrupts)); + + spin_lock(&b->lock); + for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { + struct intel_wait *w = container_of(rb, typeof(*w), node); + + seq_printf(m, "Waiting (%s): %s [%d] on %x\n", + engine->name, w->tsk->comm, w->tsk->pid, w->seqno); + } + spin_unlock(&b->lock); } static int i915_gem_seqno_info(struct seq_file *m, void *data) @@ -1428,6 +1440,8 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) engine->hangcheck.seqno, seqno[id], engine->last_submitted_seqno); + seq_printf(m, "\twaiters? %d\n", + intel_engine_has_waiter(engine)); seq_printf(m, "\tuser interrupts = %x [current %x]\n", engine->hangcheck.user_interrupts, READ_ONCE(engine->user_interrupts)); @@ -2415,7 +2429,7 @@ static int count_irq_waiters(struct drm_i915_private *i915) int count = 0; for_each_engine(engine, i915) - count += engine->irq_refcount; + count += intel_engine_has_waiter(engine); return count; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0d0e4ac4dadb..1fefa8c495f2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -506,6 +506,7 @@ struct drm_i915_error_state { bool valid; /* Software tracked state */ bool waiting; + int num_waiters; int hangcheck_score; enum intel_ring_hangcheck_action hangcheck_action; int num_requests; @@ -551,6 +552,12 @@ struct drm_i915_error_state { u32 tail; } *requests; + struct drm_i915_error_waiter { + char comm[TASK_COMM_LEN]; + pid_t pid; + u32 seqno; + } *waiters; + struct { u32 gfx_mode; union { @@ -1429,7 +1436,7 @@ struct i915_gpu_error { #define I915_STOP_RING_ALLOW_WARN (1 << 30) /* For missed irq/seqno simulation. */ - unsigned int test_irq_rings; + unsigned long test_irq_rings; }; enum modeset_restore { @@ -3064,7 +3071,6 @@ ibx_disable_display_interrupt(struct drm_i915_private *dev_priv, uint32_t bits) ibx_display_interrupt_update(dev_priv, bits, 0); } - /* i915_gem.c */ int i915_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -3975,4 +3981,34 @@ static inline void i915_trace_irq_get(struct intel_engine_cs *engine, i915_gem_request_assign(&engine->trace_irq_req, req); } +static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) +{ + /* Ensure our read of the seqno is coherent so that we + * do not "miss an interrupt" (i.e. if this is the last + * request and the seqno write from the GPU is not visible + * by the time the interrupt fires, we will see that the + * request is incomplete and go back to sleep awaiting + * another interrupt that will never come.) + * + * Strictly, we only need to do this once after an interrupt, + * but it is easier and safer to do it every time the waiter + * is woken. + */ + if (i915_gem_request_completed(req, false)) + return true; + + /* We need to check whether any gpu reset happened in between + * the request being submitted and now. If a reset has occurred, + * the seqno will have been advance past ours and our request + * is complete. If we are in the process of handling a reset, + * the request is effectively complete as the rendering will + * be discarded, but we need to return in order to drop the + * struct_mutex. + */ + if (i915_reset_in_progress(&req->i915->gpu_error)) + return true; + + return false; +} + #endif diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b5278d117ea0..c9814572e346 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1343,17 +1343,6 @@ i915_gem_check_wedge(unsigned reset_counter, bool interruptible) return 0; } -static void fake_irq(unsigned long data) -{ - wake_up_process((struct task_struct *)data); -} - -static bool missed_irq(struct drm_i915_private *dev_priv, - struct intel_engine_cs *engine) -{ - return test_bit(engine->id, &dev_priv->gpu_error.missed_irq_rings); -} - static unsigned long local_clock_us(unsigned *cpu) { unsigned long t; @@ -1386,7 +1375,7 @@ static bool busywait_stop(unsigned long timeout, unsigned cpu) return this_cpu != cpu; } -static int __i915_spin_request(struct drm_i915_gem_request *req, int state) +static bool __i915_spin_request(struct drm_i915_gem_request *req, int state) { unsigned long timeout; unsigned cpu; @@ -1401,17 +1390,14 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state) * takes to sleep on a request, on the order of a microsecond. */ - if (req->engine->irq_refcount) - return -EBUSY; - /* Only spin if we know the GPU is processing this request */ if (!i915_gem_request_started(req, true)) - return -EAGAIN; + return false; timeout = local_clock_us(&cpu) + 5; - while (!need_resched()) { + do { if (i915_gem_request_completed(req, true)) - return 0; + return true; if (signal_pending_state(state, current)) break; @@ -1420,12 +1406,9 @@ static int __i915_spin_request(struct drm_i915_gem_request *req, int state) break; cpu_relax_lowlatency(); - } - - if (i915_gem_request_completed(req, false)) - return 0; + } while (!need_resched()); - return -EAGAIN; + return false; } /** @@ -1450,18 +1433,14 @@ int __i915_wait_request(struct drm_i915_gem_request *req, s64 *timeout, struct intel_rps_client *rps) { - struct intel_engine_cs *engine = i915_gem_request_get_engine(req); - struct drm_i915_private *dev_priv = req->i915; - const bool irq_test_in_progress = - ACCESS_ONCE(dev_priv->gpu_error.test_irq_rings) & intel_engine_flag(engine); int state = interruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; DEFINE_WAIT(reset); - DEFINE_WAIT(wait); - unsigned long timeout_expire; + struct intel_wait wait; + unsigned long timeout_remain; s64 before = 0; /* Only to silence a compiler warning. */ - int ret; + int ret = 0; - WARN(!intel_irqs_enabled(dev_priv), "IRQs disabled"); + might_sleep(); if (list_empty(&req->list)) return 0; @@ -1469,7 +1448,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, if (i915_gem_request_completed(req, true)) return 0; - timeout_expire = 0; + timeout_remain = MAX_SCHEDULE_TIMEOUT; if (timeout) { if (WARN_ON(*timeout < 0)) return -EINVAL; @@ -1477,7 +1456,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, if (*timeout == 0) return -ETIME; - timeout_expire = jiffies + nsecs_to_jiffies_timeout(*timeout); + timeout_remain = nsecs_to_jiffies_timeout(*timeout); /* * Record current time in case interrupted by signal, or wedged. @@ -1485,55 +1464,32 @@ int __i915_wait_request(struct drm_i915_gem_request *req, before = ktime_get_raw_ns(); } - if (INTEL_INFO(dev_priv)->gen >= 6) - gen6_rps_boost(dev_priv, rps, req->emitted_jiffies); - trace_i915_gem_request_wait_begin(req); - /* Optimistic spin for the next jiffie before touching IRQs */ - ret = __i915_spin_request(req, state); - if (ret == 0) - goto out; + if (INTEL_INFO(req->i915)->gen >= 6) + gen6_rps_boost(req->i915, rps, req->emitted_jiffies); - if (!irq_test_in_progress && WARN_ON(!engine->irq_get(engine))) { - ret = -ENODEV; - goto out; - } + /* Optimistic spin for the next ~jiffie before touching IRQs */ + if (__i915_spin_request(req, state)) + goto complete; - add_wait_queue(&dev_priv->gpu_error.wait_queue, &reset); - for (;;) { - struct timer_list timer; + set_current_state(state); + add_wait_queue(&req->i915->gpu_error.wait_queue, &reset); - prepare_to_wait(&engine->irq_queue, &wait, state); - - /* We need to check whether any gpu reset happened in between - * the request being submitted and now. If a reset has occurred, - * the seqno will have been advance past ours and our request - * is complete. If we are in the process of handling a reset, - * the request is effectively complete as the rendering will - * be discarded, but we need to return in order to drop the - * struct_mutex. + intel_wait_init(&wait, req->seqno); + if (intel_engine_add_wait(req->engine, &wait)) + /* In order to check that we haven't missed the interrupt + * as we enabled it, we need to kick ourselves to do a + * coherent check on the seqno before we sleep. */ - if (i915_reset_in_progress(&dev_priv->gpu_error)) { - ret = 0; - break; - } - - if (i915_gem_request_completed(req, false)) { - ret = 0; - break; - } + goto wakeup; + for (;;) { if (signal_pending_state(state, current)) { ret = -ERESTARTSYS; break; } - if (timeout && time_after_eq(jiffies, timeout_expire)) { - ret = -ETIME; - break; - } - /* Ensure that even if the GPU hangs, we get woken up. * * However, note that if no one is waiting, we never notice @@ -1541,32 +1497,33 @@ int __i915_wait_request(struct drm_i915_gem_request *req, * held by the GPU and so trigger a hangcheck. In the most * pathological case, this will be upon memory starvation! */ - i915_queue_hangcheck(dev_priv); - - timer.function = NULL; - if (timeout || missed_irq(dev_priv, engine)) { - unsigned long expire; + i915_queue_hangcheck(req->i915); - setup_timer_on_stack(&timer, fake_irq, (unsigned long)current); - expire = missed_irq(dev_priv, engine) ? jiffies + 1 : timeout_expire; - mod_timer(&timer, expire); + timeout_remain = io_schedule_timeout(timeout_remain); + if (timeout_remain == 0) { + ret = -ETIME; + break; } - io_schedule(); - - if (timer.function) { - del_singleshot_timer_sync(&timer); - destroy_timer_on_stack(&timer); - } - } - remove_wait_queue(&dev_priv->gpu_error.wait_queue, &reset); + if (intel_wait_complete(&wait)) + break; - if (!irq_test_in_progress) - engine->irq_put(engine); + set_current_state(state); - finish_wait(&engine->irq_queue, &wait); +wakeup: + /* Carefully check if the request is complete, giving time + * for the seqno to be visible following the interrupt. + * We also have to check in case we are kicked by the GPU + * reset in order to drop the struct_mutex. + */ + if (__i915_request_irq_complete(req)) + break; + } + remove_wait_queue(&req->i915->gpu_error.wait_queue, &reset); -out: + intel_engine_remove_wait(req->engine, &wait); + __set_current_state(TASK_RUNNING); +complete: trace_i915_gem_request_wait_end(req); if (timeout) { @@ -2796,6 +2753,12 @@ i915_gem_init_seqno(struct drm_i915_private *dev_priv, u32 seqno) } i915_gem_retire_requests(dev_priv); + /* If the seqno wraps around, we need to clear the breadcrumb rbtree */ + if (!i915_seqno_passed(seqno, dev_priv->next_seqno)) { + while (intel_kick_waiters(dev_priv)) + yield(); + } + /* Finally reset hw state */ for_each_engine(engine, dev_priv) intel_ring_init_seqno(engine, seqno); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 34ff2459ceea..250f0b818099 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -463,6 +463,18 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, } } + if (error->ring[i].num_waiters) { + err_printf(m, "%s --- %d waiters\n", + dev_priv->engine[i].name, + error->ring[i].num_waiters); + for (j = 0; j < error->ring[i].num_waiters; j++) { + err_printf(m, " seqno 0x%08x for %s [%d]\n", + error->ring[i].waiters[j].seqno, + error->ring[i].waiters[j].comm, + error->ring[i].waiters[j].pid); + } + } + if ((obj = error->ring[i].ringbuffer)) { err_printf(m, "%s --- ringbuffer = 0x%08x\n", dev_priv->engine[i].name, @@ -605,8 +617,9 @@ static void i915_error_state_free(struct kref *error_ref) i915_error_object_free(error->ring[i].ringbuffer); i915_error_object_free(error->ring[i].hws_page); i915_error_object_free(error->ring[i].ctx); - kfree(error->ring[i].requests); i915_error_object_free(error->ring[i].wa_ctx); + kfree(error->ring[i].requests); + kfree(error->ring[i].waiters); } i915_error_object_free(error->semaphore_obj); @@ -892,6 +905,48 @@ static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, } } +static void engine_record_waiters(struct intel_engine_cs *engine, + struct drm_i915_error_ring *ering) +{ + struct intel_breadcrumbs *b = &engine->breadcrumbs; + struct drm_i915_error_waiter *waiter; + struct rb_node *rb; + int count; + + ering->num_waiters = 0; + ering->waiters = NULL; + + spin_lock(&b->lock); + count = 0; + for (rb = rb_first(&b->waiters); rb != NULL; rb = rb_next(rb)) + count++; + spin_unlock(&b->lock); + + waiter = NULL; + if (count) + waiter = kmalloc_array(count, + sizeof(struct drm_i915_error_waiter), + GFP_ATOMIC); + if (!waiter) + return; + + ering->waiters = waiter; + + spin_lock(&b->lock); + for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { + struct intel_wait *w = container_of(rb, typeof(*w), node); + + strcpy(waiter->comm, w->tsk->comm); + waiter->pid = w->tsk->pid; + waiter->seqno = w->seqno; + waiter++; + + if (++ering->num_waiters == count) + break; + } + spin_unlock(&b->lock); +} + static void i915_record_ring_state(struct drm_i915_private *dev_priv, struct drm_i915_error_state *error, struct intel_engine_cs *engine, @@ -926,7 +981,7 @@ static void i915_record_ring_state(struct drm_i915_private *dev_priv, ering->instdone = I915_READ(GEN2_INSTDONE); } - ering->waiting = waitqueue_active(&engine->irq_queue); + ering->waiting = intel_engine_has_waiter(engine); ering->instpm = I915_READ(RING_INSTPM(engine->mmio_base)); ering->acthd = intel_ring_get_active_head(engine); ering->seqno = engine->get_seqno(engine); @@ -1032,6 +1087,7 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, error->ring[i].valid = true; i915_record_ring_state(dev_priv, error, engine, &error->ring[i]); + engine_record_waiters(engine, &error->ring[i]); request = i915_gem_find_active_request(engine); if (request) { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6c17596d75dd..a11ab00cdee0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -976,13 +976,10 @@ static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) static void notify_ring(struct intel_engine_cs *engine) { - if (!intel_engine_initialized(engine)) - return; - - trace_i915_gem_request_notify(engine); - engine->user_interrupts++; - - wake_up_all(&engine->irq_queue); + if (intel_engine_wakeup(engine)) { + trace_i915_gem_request_notify(engine); + engine->user_interrupts++; + } } static void vlv_c0_read(struct drm_i915_private *dev_priv, @@ -1063,7 +1060,7 @@ static bool any_waiters(struct drm_i915_private *dev_priv) struct intel_engine_cs *engine; for_each_engine(engine, dev_priv) - if (engine->irq_refcount) + if (intel_engine_has_waiter(engine)) return true; return false; @@ -3074,13 +3071,14 @@ static unsigned kick_waiters(struct intel_engine_cs *engine) if (engine->hangcheck.user_interrupts == user_interrupts && !test_and_set_bit(engine->id, &i915->gpu_error.missed_irq_rings)) { - if (!(i915->gpu_error.test_irq_rings & intel_engine_flag(engine))) + if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings)) DRM_ERROR("Hangcheck timer elapsed... %s idle\n", engine->name); else DRM_INFO("Fake missed irq on %s\n", engine->name); - wake_up_all(&engine->irq_queue); + + intel_engine_enable_fake_irq(engine); } return user_interrupts; @@ -3124,7 +3122,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) intel_uncore_arm_unclaimed_mmio_detection(dev_priv); for_each_engine_id(engine, dev_priv, id) { - bool busy = waitqueue_active(&engine->irq_queue); + bool busy = intel_engine_has_waiter(engine); u64 acthd; u32 seqno; unsigned user_interrupts; diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c new file mode 100644 index 000000000000..a3bbf2d90dce --- /dev/null +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -0,0 +1,380 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, 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. + * + */ + +#include "i915_drv.h" + +static void intel_breadcrumbs_fake_irq(unsigned long data) +{ + struct intel_engine_cs *engine = (struct intel_engine_cs *)data; + + /* + * The timer persists in case we cannot enable interrupts, + * or if we have previously seen seqno/interrupt incoherency + * ("missed interrupt" syndrome). Here the worker will wake up + * every jiffie in order to kick the oldest waiter to do the + * coherent seqno check. + */ + rcu_read_lock(); + if (intel_engine_wakeup(engine)) + mod_timer(&engine->breadcrumbs.fake_irq, jiffies + 1); + rcu_read_unlock(); +} + +static void irq_enable(struct intel_engine_cs *engine) +{ + WARN_ON(!engine->irq_get(engine)); +} + +static void irq_disable(struct intel_engine_cs *engine) +{ + engine->irq_put(engine); +} + +static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) +{ + struct intel_engine_cs *engine = + container_of(b, struct intel_engine_cs, breadcrumbs); + struct drm_i915_private *i915 = engine->i915; + bool irq_posted = false; + + assert_spin_locked(&b->lock); + if (b->rpm_wakelock) + return false; + + /* Since we are waiting on a request, the GPU should be busy + * and should have its own rpm reference. For completeness, + * record an rpm reference for ourselves to cover the + * interrupt we unmask. + */ + intel_runtime_pm_get_noresume(i915); + b->rpm_wakelock = true; + + /* No interrupts? Kick the waiter every jiffie! */ + if (intel_irqs_enabled(i915)) { + if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings)) { + irq_enable(engine); + irq_posted = true; + } + b->irq_enabled = true; + } + + if (!b->irq_enabled || + test_bit(engine->id, &i915->gpu_error.missed_irq_rings)) + mod_timer(&b->fake_irq, jiffies + 1); + + return irq_posted; +} + +static void __intel_breadcrumbs_disable_irq(struct intel_breadcrumbs *b) +{ + struct intel_engine_cs *engine = + container_of(b, struct intel_engine_cs, breadcrumbs); + + assert_spin_locked(&b->lock); + if (!b->rpm_wakelock) + return; + + if (b->irq_enabled) { + irq_disable(engine); + b->irq_enabled = false; + } + + intel_runtime_pm_put(engine->i915); + b->rpm_wakelock = false; +} + +static inline struct intel_wait *to_wait(struct rb_node *node) +{ + return container_of(node, struct intel_wait, node); +} + +static inline void __intel_breadcrumbs_finish(struct intel_breadcrumbs *b, + struct intel_wait *wait) +{ + assert_spin_locked(&b->lock); + + /* This request is completed, so remove it from the tree, mark it as + * complete, and *then* wake up the associated task. + */ + rb_erase(&wait->node, &b->waiters); + RB_CLEAR_NODE(&wait->node); + + wake_up_process(wait->tsk); /* implicit smp_wmb() */ +} + +static bool __intel_engine_add_wait(struct intel_engine_cs *engine, + struct intel_wait *wait) +{ + struct intel_breadcrumbs *b = &engine->breadcrumbs; + struct rb_node **p, *parent, *completed; + bool first; + u32 seqno; + + /* Insert the request into the retirement ordered list + * of waiters by walking the rbtree. If we are the oldest + * seqno in the tree (the first to be retired), then + * set ourselves as the bottom-half. + * + * As we descend the tree, prune completed branches since we hold the + * spinlock we know that the first_waiter must be delayed and can + * reduce some of the sequential wake up latency if we take action + * ourselves and wake up the completed tasks in parallel. Also, by + * removing stale elements in the tree, we may be able to reduce the + * ping-pong between the old bottom-half and ourselves as first-waiter. + */ + first = true; + parent = NULL; + completed = NULL; + seqno = engine->get_seqno(engine); + + /* If the request completed before we managed to grab the spinlock, + * return now before adding ourselves to the rbtree. We let the + * current bottom-half handle any pending wakeups and instead + * try and get out of the way quickly. + */ + if (i915_seqno_passed(seqno, wait->seqno)) { + RB_CLEAR_NODE(&wait->node); + return first; + } + + p = &b->waiters.rb_node; + while (*p) { + parent = *p; + if (wait->seqno == to_wait(parent)->seqno) { + /* We have multiple waiters on the same seqno, select + * the highest priority task (that with the smallest + * task->prio) to serve as the bottom-half for this + * group. + */ + if (wait->tsk->prio > to_wait(parent)->tsk->prio) { + p = &parent->rb_right; + first = false; + } else { + p = &parent->rb_left; + } + } else if (i915_seqno_passed(wait->seqno, + to_wait(parent)->seqno)) { + p = &parent->rb_right; + if (i915_seqno_passed(seqno, to_wait(parent)->seqno)) + completed = parent; + else + first = false; + } else { + p = &parent->rb_left; + } + } + rb_link_node(&wait->node, parent, p); + rb_insert_color(&wait->node, &b->waiters); + GEM_BUG_ON(!first && !b->tasklet); + + if (completed) { + struct rb_node *next = rb_next(completed); + + GEM_BUG_ON(!next && !first); + if (next && next != &wait->node) { + GEM_BUG_ON(first); + b->first_wait = to_wait(next); + smp_store_mb(b->tasklet, b->first_wait->tsk); + /* As there is a delay between reading the current + * seqno, processing the completed tasks and selecting + * the next waiter, we may have missed the interrupt + * and so need for the next bottom-half to wakeup. + * + * Also as we enable the IRQ, we may miss the + * interrupt for that seqno, so we have to wake up + * the next bottom-half in order to do a coherent check + * in case the seqno passed. + */ + __intel_breadcrumbs_enable_irq(b); + wake_up_process(to_wait(next)->tsk); + } + + do { + struct intel_wait *crumb = to_wait(completed); + completed = rb_prev(completed); + __intel_breadcrumbs_finish(b, crumb); + } while (completed); + } + + if (first) { + GEM_BUG_ON(rb_first(&b->waiters) != &wait->node); + b->first_wait = wait; + smp_store_mb(b->tasklet, wait->tsk); + first = __intel_breadcrumbs_enable_irq(b); + } + GEM_BUG_ON(!b->tasklet); + GEM_BUG_ON(!b->first_wait); + GEM_BUG_ON(rb_first(&b->waiters) != &b->first_wait->node); + + return first; +} + +bool intel_engine_add_wait(struct intel_engine_cs *engine, + struct intel_wait *wait) +{ + struct intel_breadcrumbs *b = &engine->breadcrumbs; + bool first; + + spin_lock(&b->lock); + first = __intel_engine_add_wait(engine, wait); + spin_unlock(&b->lock); + + return first; +} + +void intel_engine_enable_fake_irq(struct intel_engine_cs *engine) +{ + mod_timer(&engine->breadcrumbs.fake_irq, jiffies + 1); +} + +static inline bool chain_wakeup(struct rb_node *rb, int priority) +{ + return rb && to_wait(rb)->tsk->prio <= priority; +} + +void intel_engine_remove_wait(struct intel_engine_cs *engine, + struct intel_wait *wait) +{ + struct intel_breadcrumbs *b = &engine->breadcrumbs; + + /* Quick check to see if this waiter was already decoupled from + * the tree by the bottom-half to avoid contention on the spinlock + * by the herd. + */ + if (RB_EMPTY_NODE(&wait->node)) + return; + + spin_lock(&b->lock); + + if (RB_EMPTY_NODE(&wait->node)) + goto out_unlock; + + if (b->first_wait == wait) { + struct rb_node *next; + const int priority = wait->tsk->prio; + + GEM_BUG_ON(b->tasklet != wait->tsk); + + /* We are the current bottom-half. Find the next candidate, + * the first waiter in the queue on the remaining oldest + * request. As multiple seqnos may complete in the time it + * takes us to wake up and find the next waiter, we have to + * wake up that waiter for it to perform its own coherent + * completion check. + */ + next = rb_next(&wait->node); + if (chain_wakeup(next, priority)) { + /* If the next waiter is already complete, + * wake it up and continue onto the next waiter. So + * if have a small herd, they will wake up in parallel + * rather than sequentially, which should reduce + * the overall latency in waking all the completed + * clients. + * + * However, waking up a chain adds extra latency to + * the first_waiter. This is undesirable if that + * waiter is a high priority task. + */ + u32 seqno = engine->get_seqno(engine); + + while (i915_seqno_passed(seqno, to_wait(next)->seqno)) { + struct rb_node *n = rb_next(next); + + __intel_breadcrumbs_finish(b, to_wait(next)); + next = n; + if (!chain_wakeup(next, priority)) + break; + } + } + + if (next) { + /* In our haste, we may have completed the first waiter + * before we enabled the interrupt. Do so now as we + * have a second waiter for a future seqno. Afterwards, + * we have to wake up that waiter in case we missed + * the interrupt, or if we have to handle an + * exception rather than a seqno completion. + */ + b->first_wait = to_wait(next); + smp_store_mb(b->tasklet, b->first_wait->tsk); + if (b->first_wait->seqno != wait->seqno) + __intel_breadcrumbs_enable_irq(b); + wake_up_process(b->tasklet); + } else { + b->first_wait = NULL; + WRITE_ONCE(b->tasklet, NULL); + __intel_breadcrumbs_disable_irq(b); + } + } else { + GEM_BUG_ON(rb_first(&b->waiters) == &wait->node); + } + + GEM_BUG_ON(RB_EMPTY_NODE(&wait->node)); + rb_erase(&wait->node, &b->waiters); + +out_unlock: + GEM_BUG_ON(b->first_wait == wait); + GEM_BUG_ON(rb_first(&b->waiters) != + (b->first_wait ? &b->first_wait->node : NULL)); + GEM_BUG_ON(!b->tasklet ^ RB_EMPTY_ROOT(&b->waiters)); + spin_unlock(&b->lock); +} + +int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine) +{ + struct intel_breadcrumbs *b = &engine->breadcrumbs; + + spin_lock_init(&b->lock); + setup_timer(&b->fake_irq, + intel_breadcrumbs_fake_irq, + (unsigned long)engine); + + return 0; +} + +void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine) +{ + struct intel_breadcrumbs *b = &engine->breadcrumbs; + + del_timer_sync(&b->fake_irq); +} + +unsigned int intel_kick_waiters(struct drm_i915_private *i915) +{ + struct intel_engine_cs *engine; + unsigned int mask = 0; + + /* To avoid the task_struct disappearing beneath us as we wake up + * the process, we must first inspect the task_struct->state under the + * RCU lock, i.e. as we call wake_up_process() we must be holding the + * rcu_read_lock(). + */ + rcu_read_lock(); + for_each_engine(engine, i915) + if (unlikely(intel_engine_wakeup(engine))) + mask |= intel_engine_flag(engine); + rcu_read_unlock(); + + return mask; +} diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 339d8041075f..226bba22e4b4 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1961,6 +1961,8 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine) i915_cmd_parser_fini_ring(engine); i915_gem_batch_pool_fini(&engine->batch_pool); + intel_engine_fini_breadcrumbs(engine); + if (engine->status_page.obj) { i915_gem_object_unpin_map(engine->status_page.obj); engine->status_page.obj = NULL; @@ -1998,7 +2000,6 @@ logical_ring_default_irqs(struct intel_engine_cs *engine, unsigned shift) { engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT << shift; engine->irq_keep_mask = GT_CONTEXT_SWITCH_INTERRUPT << shift; - init_waitqueue_head(&engine->irq_queue); } static int @@ -2025,6 +2026,10 @@ logical_ring_init(struct intel_engine_cs *engine) struct i915_gem_context *dctx = engine->i915->kernel_context; int ret; + ret = intel_engine_init_breadcrumbs(engine); + if (ret) + goto error; + ret = i915_cmd_parser_init_ring(engine); if (ret) goto error; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 24cdc920f4b4..af50aa01bcd9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2394,7 +2394,9 @@ static int intel_init_ring_buffer(struct drm_device *dev, memset(engine->semaphore.sync_seqno, 0, sizeof(engine->semaphore.sync_seqno)); - init_waitqueue_head(&engine->irq_queue); + ret = intel_engine_init_breadcrumbs(engine); + if (ret) + goto error; /* We may need to do things with the shrinker which * require us to immediately switch back to the default @@ -2474,6 +2476,7 @@ void intel_cleanup_engine(struct intel_engine_cs *engine) i915_cmd_parser_fini_ring(engine); i915_gem_batch_pool_fini(&engine->batch_pool); + intel_engine_fini_breadcrumbs(engine); intel_ring_context_unpin(dev_priv->kernel_context, engine); @@ -2676,6 +2679,13 @@ void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno) engine->last_submitted_seqno = seqno; engine->hangcheck.seqno = seqno; + + /* After manually advancing the seqno, fake the interrupt in case + * there are any waiters for that seqno. + */ + rcu_read_lock(); + intel_engine_wakeup(engine); + rcu_read_unlock(); } static void gen6_bsd_ring_write_tail(struct intel_engine_cs *engine, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 113d5230a6de..6fd70a56e219 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -148,6 +148,32 @@ struct intel_engine_cs { struct intel_ringbuffer *buffer; struct list_head buffers; + /* Rather than have every client wait upon all user interrupts, + * with the herd waking after every interrupt and each doing the + * heavyweight seqno dance, we delegate the task (of being the + * bottom-half of the user interrupt) to the first client. After + * every interrupt, we wake up one client, who does the heavyweight + * coherent seqno read and either goes back to sleep (if incomplete), + * or wakes up all the completed clients in parallel, before then + * transferring the bottom-half status to the next client in the queue. + * + * Compared to walking the entire list of waiters in a single dedicated + * bottom-half, we reduce the latency of the first waiter by avoiding + * a context switch, but incur additional coherent seqno reads when + * following the chain of request breadcrumbs. Since it is most likely + * that we have a single client waiting on each seqno, then reducing + * the overhead of waking that client is much preferred. + */ + struct intel_breadcrumbs { + spinlock_t lock; /* protects the lists of requests */ + struct rb_root waiters; /* sorted by retirement, priority */ + struct intel_wait *first_wait; /* oldest waiter by retirement */ + struct task_struct *tasklet; /* bh for user interrupts */ + struct timer_list fake_irq; /* used after a missed interrupt */ + bool irq_enabled; + bool rpm_wakelock; + } breadcrumbs; + /* * A pool of objects to use as shadow copies of client batch buffers * when the command parser is enabled. Prevents the client from @@ -296,8 +322,6 @@ struct intel_engine_cs { bool gpu_caches_dirty; - wait_queue_head_t irq_queue; - struct i915_gem_context *last_context; struct intel_ring_hangcheck hangcheck; @@ -483,4 +507,55 @@ static inline u32 intel_hws_seqno_address(struct intel_engine_cs *engine) return engine->status_page.gfx_addr + I915_GEM_HWS_INDEX_ADDR; } +/* intel_breadcrumbs.c -- user interrupt bottom-half for waiters */ +struct intel_wait { + struct rb_node node; + struct task_struct *tsk; + u32 seqno; +}; + +int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine); + +static inline void intel_wait_init(struct intel_wait *wait, u32 seqno) +{ + wait->tsk = current; + wait->seqno = seqno; +} + +static inline bool intel_wait_complete(const struct intel_wait *wait) +{ + return RB_EMPTY_NODE(&wait->node); +} + +bool intel_engine_add_wait(struct intel_engine_cs *engine, + struct intel_wait *wait); +void intel_engine_remove_wait(struct intel_engine_cs *engine, + struct intel_wait *wait); + +static inline bool intel_engine_has_waiter(struct intel_engine_cs *engine) +{ + return READ_ONCE(engine->breadcrumbs.tasklet); +} + +static inline bool intel_engine_wakeup(struct intel_engine_cs *engine) +{ + bool wakeup = false; + struct task_struct *tsk = READ_ONCE(engine->breadcrumbs.tasklet); + /* Note that for this not to dangerously chase a dangling pointer, + * the caller is responsible for ensure that the task remain valid for + * wake_up_process() i.e. that the RCU grace period cannot expire. + * + * Also note that tsk is likely to be in !TASK_RUNNING state so an + * early test for tsk->state != TASK_RUNNING before wake_up_process() + * is unlikely to be beneficial. + */ + if (tsk) + wakeup = wake_up_process(tsk); + return wakeup; +} + +void intel_engine_enable_fake_irq(struct intel_engine_cs *engine); +void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine); +unsigned int intel_kick_waiters(struct drm_i915_private *i915); + #endif /* _INTEL_RINGBUFFER_H_ */ -- cgit v1.2.3 From f69a02c9d57d50c7f688cf0be2b65ea9e3087fc9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:16 +0100 Subject: drm/i915: Spin after waking up for an interrupt When waiting for an interrupt (waiting for the engine to complete some work), we know we are the only waiter to be woken on this engine. We also know when the GPU has nearly completed our request (or at least started processing it), so after being woken and we detect that the GPU is active and working on our request, allow us the bottom-half (the first waiter who wakes up to handle checking the seqno after the interrupt) to spin for a very short while to reduce client latencies. The impact is minimal, there was an improvement to the realtime-vs-many clients case, but exporting the function proves useful later. However, it is tempting to adjust irq_seqno_barrier to include the spin. The problem is first ensuring that the "start-of-request" seqno is coherent as we use that as our basis for judging when it is ok to spin. If we could, spinning there could dramatically shorten some sleeps, and allow us to make the barriers more conservative to handle missed seqno writes on more platforms (all gen7+ are known to have the occasional issue, at least). Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-7-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 26 +++++++++++++++-------- drivers/gpu/drm/i915/i915_gem.c | 40 +++++++++++++++++++++--------------- drivers/gpu/drm/i915/intel_display.c | 2 +- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- 5 files changed, 45 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f522a366223d..309bb2f1a1e8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -663,7 +663,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) i915_gem_request_get_seqno(work->flip_queued_req), dev_priv->next_seqno, engine->get_seqno(engine), - i915_gem_request_completed(work->flip_queued_req, true)); + i915_gem_request_completed(work->flip_queued_req)); } else seq_printf(m, "Flip not associated with any ring\n"); seq_printf(m, "Flip queued on frame %d, (was ready on frame %d), now %d\n", diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1fefa8c495f2..0ea69c5ecc8b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3287,24 +3287,27 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) return (int32_t)(seq1 - seq2) >= 0; } -static inline bool i915_gem_request_started(struct drm_i915_gem_request *req, - bool lazy_coherency) +static inline bool i915_gem_request_started(const struct drm_i915_gem_request *req) { - if (!lazy_coherency && req->engine->irq_seqno_barrier) - req->engine->irq_seqno_barrier(req->engine); return i915_seqno_passed(req->engine->get_seqno(req->engine), req->previous_seqno); } -static inline bool i915_gem_request_completed(struct drm_i915_gem_request *req, - bool lazy_coherency) +static inline bool i915_gem_request_completed(const struct drm_i915_gem_request *req) { - if (!lazy_coherency && req->engine->irq_seqno_barrier) - req->engine->irq_seqno_barrier(req->engine); return i915_seqno_passed(req->engine->get_seqno(req->engine), req->seqno); } +bool __i915_spin_request(const struct drm_i915_gem_request *request, + int state, unsigned long timeout_us); +static inline bool i915_spin_request(const struct drm_i915_gem_request *request, + int state, unsigned long timeout_us) +{ + return (i915_gem_request_started(request) && + __i915_spin_request(request, state, timeout_us)); +} + int __must_check i915_gem_get_seqno(struct drm_i915_private *dev_priv, u32 *seqno); int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno); @@ -3983,6 +3986,8 @@ static inline void i915_trace_irq_get(struct intel_engine_cs *engine, static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) { + struct intel_engine_cs *engine = req->engine; + /* Ensure our read of the seqno is coherent so that we * do not "miss an interrupt" (i.e. if this is the last * request and the seqno write from the GPU is not visible @@ -3994,7 +3999,10 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) * but it is easier and safer to do it every time the waiter * is woken. */ - if (i915_gem_request_completed(req, false)) + if (engine->irq_seqno_barrier) + engine->irq_seqno_barrier(engine); + + if (i915_gem_request_completed(req)) return true; /* We need to check whether any gpu reset happened in between diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c9814572e346..2aef737fa761 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1375,9 +1375,9 @@ static bool busywait_stop(unsigned long timeout, unsigned cpu) return this_cpu != cpu; } -static bool __i915_spin_request(struct drm_i915_gem_request *req, int state) +bool __i915_spin_request(const struct drm_i915_gem_request *req, + int state, unsigned long timeout_us) { - unsigned long timeout; unsigned cpu; /* When waiting for high frequency requests, e.g. during synchronous @@ -1390,19 +1390,15 @@ static bool __i915_spin_request(struct drm_i915_gem_request *req, int state) * takes to sleep on a request, on the order of a microsecond. */ - /* Only spin if we know the GPU is processing this request */ - if (!i915_gem_request_started(req, true)) - return false; - - timeout = local_clock_us(&cpu) + 5; + timeout_us += local_clock_us(&cpu); do { - if (i915_gem_request_completed(req, true)) + if (i915_gem_request_completed(req)) return true; if (signal_pending_state(state, current)) break; - if (busywait_stop(timeout, cpu)) + if (busywait_stop(timeout_us, cpu)) break; cpu_relax_lowlatency(); @@ -1445,7 +1441,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, if (list_empty(&req->list)) return 0; - if (i915_gem_request_completed(req, true)) + if (i915_gem_request_completed(req)) return 0; timeout_remain = MAX_SCHEDULE_TIMEOUT; @@ -1470,7 +1466,7 @@ int __i915_wait_request(struct drm_i915_gem_request *req, gen6_rps_boost(req->i915, rps, req->emitted_jiffies); /* Optimistic spin for the next ~jiffie before touching IRQs */ - if (__i915_spin_request(req, state)) + if (i915_spin_request(req, state, 5)) goto complete; set_current_state(state); @@ -1518,6 +1514,10 @@ wakeup: */ if (__i915_request_irq_complete(req)) break; + + /* Only spin if we know the GPU is processing this request */ + if (i915_spin_request(req, state, 2)) + break; } remove_wait_queue(&req->i915->gpu_error.wait_queue, &reset); @@ -3055,8 +3055,16 @@ i915_gem_find_active_request(struct intel_engine_cs *engine) { struct drm_i915_gem_request *request; + /* We are called by the error capture and reset at a random + * point in time. In particular, note that neither is crucially + * ordered with an interrupt. After a hang, the GPU is dead and we + * assume that no more writes can happen (we waited long enough for + * all writes that were in transaction to be flushed) - adding an + * extra delay for a recent interrupt is pointless. Hence, we do + * not need an engine->irq_seqno_barrier() before the seqno reads. + */ list_for_each_entry(request, &engine->request_list, list) { - if (i915_gem_request_completed(request, false)) + if (i915_gem_request_completed(request)) continue; return request; @@ -3188,7 +3196,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *engine) struct drm_i915_gem_request, list); - if (!i915_gem_request_completed(request, true)) + if (!i915_gem_request_completed(request)) break; i915_gem_request_retire(request); @@ -3212,7 +3220,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *engine) } if (unlikely(engine->trace_irq_req && - i915_gem_request_completed(engine->trace_irq_req, true))) { + i915_gem_request_completed(engine->trace_irq_req))) { engine->irq_put(engine); i915_gem_request_assign(&engine->trace_irq_req, NULL); } @@ -3310,7 +3318,7 @@ i915_gem_object_flush_active(struct drm_i915_gem_object *obj) if (req == NULL) continue; - if (i915_gem_request_completed(req, true)) + if (i915_gem_request_completed(req)) i915_gem_object_retire__read(obj, i); } @@ -3418,7 +3426,7 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj, if (to == from) return 0; - if (i915_gem_request_completed(from_req, true)) + if (i915_gem_request_completed(from_req)) return 0; if (!i915_semaphore_is_enabled(to_i915(obj->base.dev))) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 30c181a72202..88e899b46853 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11628,7 +11628,7 @@ static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv, vblank = intel_crtc_get_vblank_counter(intel_crtc); if (work->flip_ready_vblank == 0) { if (work->flip_queued_req && - !i915_gem_request_completed(work->flip_queued_req, true)) + !i915_gem_request_completed(work->flip_queued_req)) return false; work->flip_ready_vblank = vblank; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index cfe850f8815a..82c2efdcdd89 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7767,7 +7767,7 @@ static void __intel_rps_boost_work(struct work_struct *work) struct request_boost *boost = container_of(work, struct request_boost, work); struct drm_i915_gem_request *req = boost->req; - if (!i915_gem_request_completed(req, true)) + if (!i915_gem_request_completed(req)) gen6_rps_boost(req->i915, NULL, req->emitted_jiffies); i915_gem_request_unreference(req); @@ -7781,7 +7781,7 @@ void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req) if (req == NULL || INTEL_GEN(req->i915) < 6) return; - if (i915_gem_request_completed(req, true)) + if (i915_gem_request_completed(req)) return; boost = kmalloc(sizeof(*boost), GFP_ATOMIC); -- cgit v1.2.3 From 1b7744e7ba4e4ad17b5910796c9b1ca74063df01 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:17 +0100 Subject: drm/i915: Use HWS for seqno tracking everywhere By using the same address for storing the HWS on every platform, we can remove the platform specific vfuncs and reduce the get-seqno routine to a single read of a cached memory location. v2: Fix semaphore_passed() to look at the signaling engine (not the waiter's) Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-8-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 6 +-- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- drivers/gpu/drm/i915/i915_irq.c | 4 +- drivers/gpu/drm/i915/i915_trace.h | 2 +- drivers/gpu/drm/i915/intel_breadcrumbs.c | 4 +- drivers/gpu/drm/i915/intel_lrc.c | 26 +------------ drivers/gpu/drm/i915/intel_ringbuffer.c | 65 +++++++++----------------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 7 ++-- 9 files changed, 34 insertions(+), 86 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 309bb2f1a1e8..f5899b631c0e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -662,7 +662,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) engine->name, i915_gem_request_get_seqno(work->flip_queued_req), dev_priv->next_seqno, - engine->get_seqno(engine), + intel_engine_get_seqno(engine), i915_gem_request_completed(work->flip_queued_req)); } else seq_printf(m, "Flip not associated with any ring\n"); @@ -792,7 +792,7 @@ static void i915_ring_seqno_info(struct seq_file *m, struct rb_node *rb; seq_printf(m, "Current sequence (%s): %x\n", - engine->name, engine->get_seqno(engine)); + engine->name, intel_engine_get_seqno(engine)); seq_printf(m, "Current user interrupts (%s): %x\n", engine->name, READ_ONCE(engine->user_interrupts)); @@ -1420,7 +1420,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) for_each_engine_id(engine, dev_priv, id) { acthd[id] = intel_ring_get_active_head(engine); - seqno[id] = engine->get_seqno(engine); + seqno[id] = intel_engine_get_seqno(engine); } i915_get_extra_instdone(dev_priv, instdone); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0ea69c5ecc8b..5a1e8e056ee5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3289,13 +3289,13 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) static inline bool i915_gem_request_started(const struct drm_i915_gem_request *req) { - return i915_seqno_passed(req->engine->get_seqno(req->engine), + return i915_seqno_passed(intel_engine_get_seqno(req->engine), req->previous_seqno); } static inline bool i915_gem_request_completed(const struct drm_i915_gem_request *req) { - return i915_seqno_passed(req->engine->get_seqno(req->engine), + return i915_seqno_passed(intel_engine_get_seqno(req->engine), req->seqno); } diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 250f0b818099..1c15a74530cd 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -984,7 +984,7 @@ static void i915_record_ring_state(struct drm_i915_private *dev_priv, ering->waiting = intel_engine_has_waiter(engine); ering->instpm = I915_READ(RING_INSTPM(engine->mmio_base)); ering->acthd = intel_ring_get_active_head(engine); - ering->seqno = engine->get_seqno(engine); + ering->seqno = intel_engine_get_seqno(engine); ering->last_seqno = engine->last_submitted_seqno; ering->start = I915_READ_START(engine); ering->head = I915_READ_HEAD(engine); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a11ab00cdee0..7c379afcff2f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2952,7 +2952,7 @@ static int semaphore_passed(struct intel_engine_cs *engine) if (signaller->hangcheck.deadlock >= I915_NUM_ENGINES) return -1; - if (i915_seqno_passed(signaller->get_seqno(signaller), seqno)) + if (i915_seqno_passed(intel_engine_get_seqno(signaller), seqno)) return 1; /* cursory check for an unkickable deadlock */ @@ -3140,7 +3140,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) engine->irq_seqno_barrier(engine); acthd = intel_ring_get_active_head(engine); - seqno = engine->get_seqno(engine); + seqno = intel_engine_get_seqno(engine); /* Reset stuck interrupts between batch advances */ user_interrupts = 0; diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 6768db032f84..3d13fde95fdf 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -558,7 +558,7 @@ TRACE_EVENT(i915_gem_request_notify, TP_fast_assign( __entry->dev = engine->i915->dev->primary->index; __entry->ring = engine->id; - __entry->seqno = engine->get_seqno(engine); + __entry->seqno = intel_engine_get_seqno(engine); ), TP_printk("dev=%u, ring=%u, seqno=%u", diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index a3bbf2d90dce..7cdb02d18c1f 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -146,7 +146,7 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, first = true; parent = NULL; completed = NULL; - seqno = engine->get_seqno(engine); + seqno = intel_engine_get_seqno(engine); /* If the request completed before we managed to grab the spinlock, * return now before adding ourselves to the rbtree. We let the @@ -296,7 +296,7 @@ void intel_engine_remove_wait(struct intel_engine_cs *engine, * the first_waiter. This is undesirable if that * waiter is a high priority task. */ - u32 seqno = engine->get_seqno(engine); + u32 seqno = intel_engine_get_seqno(engine); while (i915_seqno_passed(seqno, to_wait(next)->seqno)) { struct rb_node *n = rb_next(next); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 226bba22e4b4..c8411f8bb4ac 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1783,16 +1783,6 @@ static int gen8_emit_flush_render(struct drm_i915_gem_request *request, return 0; } -static u32 gen8_get_seqno(struct intel_engine_cs *engine) -{ - return intel_read_status_page(engine, I915_GEM_HWS_INDEX); -} - -static void gen8_set_seqno(struct intel_engine_cs *engine, u32 seqno) -{ - intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); -} - static void bxt_a_seqno_barrier(struct intel_engine_cs *engine) { /* @@ -1808,14 +1798,6 @@ static void bxt_a_seqno_barrier(struct intel_engine_cs *engine) intel_flush_status_page(engine, I915_GEM_HWS_INDEX); } -static void bxt_a_set_seqno(struct intel_engine_cs *engine, u32 seqno) -{ - intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); - - /* See bxt_a_get_seqno() explaining the reason for the clflush. */ - intel_flush_status_page(engine, I915_GEM_HWS_INDEX); -} - /* * Reserve space for 2 NOOPs at the end of each request to be * used as a workaround for not being allowed to do lite @@ -1841,7 +1823,7 @@ static int gen8_emit_request(struct drm_i915_gem_request *request) intel_hws_seqno_address(request->engine) | MI_FLUSH_DW_USE_GTT); intel_logical_ring_emit(ringbuf, 0); - intel_logical_ring_emit(ringbuf, i915_gem_request_get_seqno(request)); + intel_logical_ring_emit(ringbuf, request->seqno); intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); intel_logical_ring_emit(ringbuf, MI_NOOP); return intel_logical_ring_advance_and_submit(request); @@ -1987,12 +1969,8 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine) engine->irq_get = gen8_logical_ring_get_irq; engine->irq_put = gen8_logical_ring_put_irq; engine->emit_bb_start = gen8_emit_bb_start; - engine->get_seqno = gen8_get_seqno; - engine->set_seqno = gen8_set_seqno; - if (IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1)) { + if (IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1)) engine->irq_seqno_barrier = bxt_a_seqno_barrier; - engine->set_seqno = bxt_a_set_seqno; - } } static inline void diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index af50aa01bcd9..02104fbf9045 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1367,19 +1367,17 @@ static int gen8_rcs_signal(struct drm_i915_gem_request *signaller_req, return ret; for_each_engine_id(waiter, dev_priv, id) { - u32 seqno; u64 gtt_offset = signaller->semaphore.signal_ggtt[id]; if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) continue; - seqno = i915_gem_request_get_seqno(signaller_req); intel_ring_emit(signaller, GFX_OP_PIPE_CONTROL(6)); intel_ring_emit(signaller, PIPE_CONTROL_GLOBAL_GTT_IVB | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_CS_STALL); intel_ring_emit(signaller, lower_32_bits(gtt_offset)); intel_ring_emit(signaller, upper_32_bits(gtt_offset)); - intel_ring_emit(signaller, seqno); + intel_ring_emit(signaller, signaller_req->seqno); intel_ring_emit(signaller, 0); intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL | MI_SEMAPHORE_TARGET(waiter->hw_id)); @@ -1408,18 +1406,16 @@ static int gen8_xcs_signal(struct drm_i915_gem_request *signaller_req, return ret; for_each_engine_id(waiter, dev_priv, id) { - u32 seqno; u64 gtt_offset = signaller->semaphore.signal_ggtt[id]; if (gtt_offset == MI_SEMAPHORE_SYNC_INVALID) continue; - seqno = i915_gem_request_get_seqno(signaller_req); intel_ring_emit(signaller, (MI_FLUSH_DW + 1) | MI_FLUSH_DW_OP_STOREDW); intel_ring_emit(signaller, lower_32_bits(gtt_offset) | MI_FLUSH_DW_USE_GTT); intel_ring_emit(signaller, upper_32_bits(gtt_offset)); - intel_ring_emit(signaller, seqno); + intel_ring_emit(signaller, signaller_req->seqno); intel_ring_emit(signaller, MI_SEMAPHORE_SIGNAL | MI_SEMAPHORE_TARGET(waiter->hw_id)); intel_ring_emit(signaller, 0); @@ -1450,11 +1446,9 @@ static int gen6_signal(struct drm_i915_gem_request *signaller_req, i915_reg_t mbox_reg = signaller->semaphore.mbox.signal[id]; if (i915_mmio_reg_valid(mbox_reg)) { - u32 seqno = i915_gem_request_get_seqno(signaller_req); - intel_ring_emit(signaller, MI_LOAD_REGISTER_IMM(1)); intel_ring_emit_reg(signaller, mbox_reg); - intel_ring_emit(signaller, seqno); + intel_ring_emit(signaller, signaller_req->seqno); } } @@ -1490,7 +1484,7 @@ gen6_add_request(struct drm_i915_gem_request *req) intel_ring_emit(engine, MI_STORE_DWORD_INDEX); intel_ring_emit(engine, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(engine, i915_gem_request_get_seqno(req)); + intel_ring_emit(engine, req->seqno); intel_ring_emit(engine, MI_USER_INTERRUPT); __intel_ring_advance(engine); @@ -1628,7 +1622,9 @@ static int pc_render_add_request(struct drm_i915_gem_request *req) { struct intel_engine_cs *engine = req->engine; - u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES; + u32 addr = engine->status_page.gfx_addr + + (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + u32 scratch_addr = addr; int ret; /* For Ironlake, MI_USER_INTERRUPT was deprecated and apparently @@ -1644,12 +1640,12 @@ pc_render_add_request(struct drm_i915_gem_request *req) return ret; intel_ring_emit(engine, - GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | + GFX_OP_PIPE_CONTROL(4) | + PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WRITE_FLUSH | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); - intel_ring_emit(engine, - engine->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(engine, i915_gem_request_get_seqno(req)); + intel_ring_emit(engine, addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(engine, req->seqno); intel_ring_emit(engine, 0); PIPE_CONTROL_FLUSH(engine, scratch_addr); scratch_addr += 2 * CACHELINE_BYTES; /* write to separate cachelines */ @@ -1668,9 +1664,8 @@ pc_render_add_request(struct drm_i915_gem_request *req) PIPE_CONTROL_WRITE_FLUSH | PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | PIPE_CONTROL_NOTIFY); - intel_ring_emit(engine, - engine->scratch.gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(engine, i915_gem_request_get_seqno(req)); + intel_ring_emit(engine, addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(engine, req->seqno); intel_ring_emit(engine, 0); __intel_ring_advance(engine); @@ -1702,30 +1697,6 @@ gen6_seqno_barrier(struct intel_engine_cs *engine) spin_unlock_irq(&dev_priv->uncore.lock); } -static u32 -ring_get_seqno(struct intel_engine_cs *engine) -{ - return intel_read_status_page(engine, I915_GEM_HWS_INDEX); -} - -static void -ring_set_seqno(struct intel_engine_cs *engine, u32 seqno) -{ - intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); -} - -static u32 -pc_render_get_seqno(struct intel_engine_cs *engine) -{ - return engine->scratch.cpu_page[0]; -} - -static void -pc_render_set_seqno(struct intel_engine_cs *engine, u32 seqno) -{ - engine->scratch.cpu_page[0] = seqno; -} - static bool gen5_ring_get_irq(struct intel_engine_cs *engine) { @@ -1856,7 +1827,7 @@ i9xx_add_request(struct drm_i915_gem_request *req) intel_ring_emit(engine, MI_STORE_DWORD_INDEX); intel_ring_emit(engine, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(engine, i915_gem_request_get_seqno(req)); + intel_ring_emit(engine, req->seqno); intel_ring_emit(engine, MI_USER_INTERRUPT); __intel_ring_advance(engine); @@ -2675,7 +2646,9 @@ void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno) memset(engine->semaphore.sync_seqno, 0, sizeof(engine->semaphore.sync_seqno)); - engine->set_seqno(engine, seqno); + intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno); + if (engine->irq_seqno_barrier) + engine->irq_seqno_barrier(engine); engine->last_submitted_seqno = seqno; engine->hangcheck.seqno = seqno; @@ -3021,8 +2994,6 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, { engine->init_hw = init_ring_common; engine->write_tail = ring_write_tail; - engine->get_seqno = ring_get_seqno; - engine->set_seqno = ring_set_seqno; engine->add_request = i9xx_add_request; if (INTEL_GEN(dev_priv) >= 6) @@ -3074,8 +3045,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) } else if (IS_GEN5(dev_priv)) { engine->add_request = pc_render_add_request; engine->flush = gen4_render_ring_flush; - engine->get_seqno = pc_render_get_seqno; - engine->set_seqno = pc_render_set_seqno; engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT; } else { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 6fd70a56e219..b03931f6dde5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -207,9 +207,6 @@ struct intel_engine_cs { * monotonic, even if not coherent. */ void (*irq_seqno_barrier)(struct intel_engine_cs *ring); - u32 (*get_seqno)(struct intel_engine_cs *ring); - void (*set_seqno)(struct intel_engine_cs *ring, - u32 seqno); int (*dispatch_execbuffer)(struct drm_i915_gem_request *req, u64 offset, u32 length, unsigned dispatch_flags); @@ -485,6 +482,10 @@ int intel_init_blt_ring_buffer(struct drm_device *dev); int intel_init_vebox_ring_buffer(struct drm_device *dev); u64 intel_ring_get_active_head(struct intel_engine_cs *engine); +static inline u32 intel_engine_get_seqno(struct intel_engine_cs *engine) +{ + return intel_read_status_page(engine, I915_GEM_HWS_INDEX); +} int init_workarounds_ring(struct intel_engine_cs *engine); -- cgit v1.2.3 From f8291952bd8c10e2dfb6fc0419ed747922ab90ea Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:18 +0100 Subject: drm/i915: Stop mapping the scratch page into CPU space After the elimination of using the scratch page for Ironlake's breadcrumb, we no longer need to kmap the object. We therefore can move it into the high unmappable space and do not need to force the object to be coherent (i.e. snooped on !llc platforms). Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-9-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c | 40 +++++++++------------------------ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 - 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 02104fbf9045..7ccfb1e57d12 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -648,58 +648,40 @@ out: return ret; } -void -intel_fini_pipe_control(struct intel_engine_cs *engine) +void intel_fini_pipe_control(struct intel_engine_cs *engine) { if (engine->scratch.obj == NULL) return; - if (INTEL_GEN(engine->i915) >= 5) { - kunmap(sg_page(engine->scratch.obj->pages->sgl)); - i915_gem_object_ggtt_unpin(engine->scratch.obj); - } - + i915_gem_object_ggtt_unpin(engine->scratch.obj); drm_gem_object_unreference(&engine->scratch.obj->base); engine->scratch.obj = NULL; } -int -intel_init_pipe_control(struct intel_engine_cs *engine) +int intel_init_pipe_control(struct intel_engine_cs *engine) { + struct drm_i915_gem_object *obj; int ret; WARN_ON(engine->scratch.obj); - engine->scratch.obj = i915_gem_object_create(engine->i915->dev, 4096); - if (IS_ERR(engine->scratch.obj)) { - DRM_ERROR("Failed to allocate seqno page\n"); - ret = PTR_ERR(engine->scratch.obj); - engine->scratch.obj = NULL; + obj = i915_gem_object_create(engine->i915->dev, 4096); + if (IS_ERR(obj)) { + DRM_ERROR("Failed to allocate scratch page\n"); + ret = PTR_ERR(obj); goto err; } - ret = i915_gem_object_set_cache_level(engine->scratch.obj, - I915_CACHE_LLC); + ret = i915_gem_obj_ggtt_pin(obj, 4096, PIN_HIGH); if (ret) goto err_unref; - ret = i915_gem_obj_ggtt_pin(engine->scratch.obj, 4096, 0); - if (ret) - goto err_unref; - - engine->scratch.gtt_offset = i915_gem_obj_ggtt_offset(engine->scratch.obj); - engine->scratch.cpu_page = kmap(sg_page(engine->scratch.obj->pages->sgl)); - if (engine->scratch.cpu_page == NULL) { - ret = -ENOMEM; - goto err_unpin; - } - + engine->scratch.obj = obj; + engine->scratch.gtt_offset = i915_gem_obj_ggtt_offset(obj); DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n", engine->name, engine->scratch.gtt_offset); return 0; -err_unpin: - i915_gem_object_ggtt_unpin(engine->scratch.obj); err_unref: drm_gem_object_unreference(&engine->scratch.obj->base); err: diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index b03931f6dde5..2ae6e3c8eb0f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -326,7 +326,6 @@ struct intel_engine_cs { struct { struct drm_i915_gem_object *obj; u32 gtt_offset; - volatile u32 *cpu_page; } scratch; bool needs_cmd_parser; -- cgit v1.2.3 From de8fe1663a5e1e6d83b21caf000f462483a8a559 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:19 +0100 Subject: drm/i915: Allocate scratch page from stolen With the last direct CPU access to the scratch page removed, we can now allocate it from our small amount of reserved system pages (stolen memory). Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-10-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7ccfb1e57d12..3bc968b7aedc 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -665,7 +665,9 @@ int intel_init_pipe_control(struct intel_engine_cs *engine) WARN_ON(engine->scratch.obj); - obj = i915_gem_object_create(engine->i915->dev, 4096); + obj = i915_gem_object_create_stolen(engine->i915->dev, 4096); + if (!obj) + obj = i915_gem_object_create(engine->i915->dev, 4096); if (IS_ERR(obj)) { DRM_ERROR("Failed to allocate scratch page\n"); ret = PTR_ERR(obj); -- cgit v1.2.3 From 7d5ea80720a8e53ff4ea309708cef2a7a0e163c7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:20 +0100 Subject: drm/i915: Refactor scratch object allocation for gen2 w/a buffer The gen2 w/a buffer is stuffed into the same slot as the gen5+ scratch buffer. If we pass in the size we want to allocate for the scratch buffer, both callers can use the same routine. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-11-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 32 ++++++++------------------------ drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index c8411f8bb4ac..f1a01137334c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2056,7 +2056,7 @@ static int logical_render_ring_init(struct intel_engine_cs *engine) engine->emit_flush = gen8_emit_flush_render; engine->emit_request = gen8_emit_request_render; - ret = intel_init_pipe_control(engine); + ret = intel_init_pipe_control(engine, 4096); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3bc968b7aedc..25d616d114e4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -658,16 +658,16 @@ void intel_fini_pipe_control(struct intel_engine_cs *engine) engine->scratch.obj = NULL; } -int intel_init_pipe_control(struct intel_engine_cs *engine) +int intel_init_pipe_control(struct intel_engine_cs *engine, int size) { struct drm_i915_gem_object *obj; int ret; WARN_ON(engine->scratch.obj); - obj = i915_gem_object_create_stolen(engine->i915->dev, 4096); + obj = i915_gem_object_create_stolen(engine->i915->dev, size); if (!obj) - obj = i915_gem_object_create(engine->i915->dev, 4096); + obj = i915_gem_object_create(engine->i915->dev, size); if (IS_ERR(obj)) { DRM_ERROR("Failed to allocate scratch page\n"); ret = PTR_ERR(obj); @@ -3002,7 +3002,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *engine = &dev_priv->engine[RCS]; - struct drm_i915_gem_object *obj; int ret; engine->name = "render ring"; @@ -3045,31 +3044,16 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->init_hw = init_render_ring; engine->cleanup = render_ring_cleanup; - /* Workaround batchbuffer to combat CS tlb bug. */ - if (HAS_BROKEN_CS_TLB(dev_priv)) { - obj = i915_gem_object_create(dev, I830_WA_SIZE); - if (IS_ERR(obj)) { - DRM_ERROR("Failed to allocate batch bo\n"); - return PTR_ERR(obj); - } - - ret = i915_gem_obj_ggtt_pin(obj, 0, 0); - if (ret != 0) { - drm_gem_object_unreference(&obj->base); - DRM_ERROR("Failed to ping batch bo\n"); - return ret; - } - - engine->scratch.obj = obj; - engine->scratch.gtt_offset = i915_gem_obj_ggtt_offset(obj); - } - ret = intel_init_ring_buffer(dev, engine); if (ret) return ret; if (INTEL_GEN(dev_priv) >= 5) { - ret = intel_init_pipe_control(engine); + ret = intel_init_pipe_control(engine, 4096); + if (ret) + return ret; + } else if (HAS_BROKEN_CS_TLB(dev_priv)) { + ret = intel_init_pipe_control(engine, I830_WA_SIZE); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 2ae6e3c8eb0f..ad86686e57f0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -471,8 +471,8 @@ void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno); int intel_ring_flush_all_caches(struct drm_i915_gem_request *req); int intel_ring_invalidate_all_caches(struct drm_i915_gem_request *req); +int intel_init_pipe_control(struct intel_engine_cs *engine, int size); void intel_fini_pipe_control(struct intel_engine_cs *engine); -int intel_init_pipe_control(struct intel_engine_cs *engine); int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev); -- cgit v1.2.3 From f8973c217f07903247d222ab92ad37e2529aff2e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:21 +0100 Subject: drm/i915: Add a delay between interrupt and inspecting the final seqno (ilk) On Ironlake, there is no command nor register to ensure that the write from a MI_STORE command is completed (and coherent on the CPU) before the command parser continues. This means that the ordering between the seqno write and the subsequent user interrupt is undefined (like gen6+). So to ensure that the seqno write is completed after the final user interrupt we need to delay the read sufficiently to allow the write to complete. This delay is undefined by the bspec, and empirically requires 75us even though a register read combined with a clflush is less than 500ns. Hence, the delay is due to an on-chip buffer rather than the latency of the write to memory. Note that the render ring controls this by filling the PIPE_CONTROL fifo with stalling commands that force the earliest pipe-control with the seqno to be completed before the command parser continues. Given that we need a barrier operation for BSD, we may as well forgo the extra per-batch latency by using a common per-interrupt barrier. Studying the impact of adding the usleep shows that in both sequences of and individual synchronous no-op batches is negligible for the media engine (where the write now is unordered with the interrupt). Converting the render engine over from the current glutton of pie-controls over to the per-interrupt delays speeds up both the sequential and individual synchronous no-ops by 20% and 60%, respectively. This speed up holds even when looking at the throughput of small copies (4KiB->4MiB), both serial and synchronous, by about 20%. This is because despite adding a significant delay to the interrupt, in all likelihood we will see the seqno write without having to apply the barrier (only in the rare corner cases where the write is delayed on the last required is the delay necessary). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94307 Testcase: igt/gem_sync #ilk Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-12-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 10 ++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 81 +++++++-------------------------- 2 files changed, 20 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7c379afcff2f..be7f0b9b27e0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1264,8 +1264,7 @@ static void ivybridge_parity_error_irq_handler(struct drm_i915_private *dev_priv static void ilk_gt_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) { - if (gt_iir & - (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)) + if (gt_iir & GT_RENDER_USER_INTERRUPT) notify_ring(&dev_priv->engine[RCS]); if (gt_iir & ILK_BSD_USER_INTERRUPT) notify_ring(&dev_priv->engine[VCS]); @@ -1274,9 +1273,7 @@ static void ilk_gt_irq_handler(struct drm_i915_private *dev_priv, static void snb_gt_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir) { - - if (gt_iir & - (GT_RENDER_USER_INTERRUPT | GT_RENDER_PIPECTL_NOTIFY_INTERRUPT)) + if (gt_iir & GT_RENDER_USER_INTERRUPT) notify_ring(&dev_priv->engine[RCS]); if (gt_iir & GT_BSD_USER_INTERRUPT) notify_ring(&dev_priv->engine[VCS]); @@ -3601,8 +3598,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) gt_irqs |= GT_RENDER_USER_INTERRUPT; if (IS_GEN5(dev)) { - gt_irqs |= GT_RENDER_PIPECTL_NOTIFY_INTERRUPT | - ILK_BSD_USER_INTERRUPT; + gt_irqs |= ILK_BSD_USER_INTERRUPT; } else { gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 25d616d114e4..3bd598673d88 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1593,67 +1593,22 @@ gen6_ring_sync(struct drm_i915_gem_request *waiter_req, return 0; } -#define PIPE_CONTROL_FLUSH(ring__, addr__) \ -do { \ - intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | \ - PIPE_CONTROL_DEPTH_STALL); \ - intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \ - intel_ring_emit(ring__, 0); \ - intel_ring_emit(ring__, 0); \ -} while (0) - -static int -pc_render_add_request(struct drm_i915_gem_request *req) +static void +gen5_seqno_barrier(struct intel_engine_cs *ring) { - struct intel_engine_cs *engine = req->engine; - u32 addr = engine->status_page.gfx_addr + - (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - u32 scratch_addr = addr; - int ret; - - /* For Ironlake, MI_USER_INTERRUPT was deprecated and apparently - * incoherent with writes to memory, i.e. completely fubar, - * so we need to use PIPE_NOTIFY instead. + /* MI_STORE are internally buffered by the GPU and not flushed + * either by MI_FLUSH or SyncFlush or any other combination of + * MI commands. * - * However, we also need to workaround the qword write - * incoherence by flushing the 6 PIPE_NOTIFY buffers out to - * memory before requesting an interrupt. + * "Only the submission of the store operation is guaranteed. + * The write result will be complete (coherent) some time later + * (this is practically a finite period but there is no guaranteed + * latency)." + * + * Empirically, we observe that we need a delay of at least 75us to + * be sure that the seqno write is visible by the CPU. */ - ret = intel_ring_begin(req, 32); - if (ret) - return ret; - - intel_ring_emit(engine, - GFX_OP_PIPE_CONTROL(4) | - PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WRITE_FLUSH | - PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); - intel_ring_emit(engine, addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(engine, req->seqno); - intel_ring_emit(engine, 0); - PIPE_CONTROL_FLUSH(engine, scratch_addr); - scratch_addr += 2 * CACHELINE_BYTES; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(engine, scratch_addr); - scratch_addr += 2 * CACHELINE_BYTES; - PIPE_CONTROL_FLUSH(engine, scratch_addr); - scratch_addr += 2 * CACHELINE_BYTES; - PIPE_CONTROL_FLUSH(engine, scratch_addr); - scratch_addr += 2 * CACHELINE_BYTES; - PIPE_CONTROL_FLUSH(engine, scratch_addr); - scratch_addr += 2 * CACHELINE_BYTES; - PIPE_CONTROL_FLUSH(engine, scratch_addr); - - intel_ring_emit(engine, - GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WRITE_FLUSH | - PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(engine, addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(engine, req->seqno); - intel_ring_emit(engine, 0); - __intel_ring_advance(engine); - - return 0; + usleep_range(125, 250); } static void @@ -2964,6 +2919,7 @@ static void intel_ring_init_irq(struct drm_i915_private *dev_priv, } else if (INTEL_GEN(dev_priv) >= 5) { engine->irq_get = gen5_ring_get_irq; engine->irq_put = gen5_ring_put_irq; + engine->irq_seqno_barrier = gen5_seqno_barrier; } else if (INTEL_GEN(dev_priv) >= 3) { engine->irq_get = i9xx_ring_get_irq; engine->irq_put = i9xx_ring_put_irq; @@ -3012,11 +2968,12 @@ int intel_init_render_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); + engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; + if (INTEL_GEN(dev_priv) >= 8) { engine->init_context = intel_rcs_ctx_init; engine->add_request = gen8_render_add_request; engine->flush = gen8_render_ring_flush; - engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; if (i915_semaphore_is_enabled(dev_priv)) engine->semaphore.signal = gen8_rcs_signal; } else if (INTEL_GEN(dev_priv) >= 6) { @@ -3024,12 +2981,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev) engine->flush = gen7_render_ring_flush; if (IS_GEN6(dev_priv)) engine->flush = gen6_render_ring_flush; - engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; } else if (IS_GEN5(dev_priv)) { - engine->add_request = pc_render_add_request; engine->flush = gen4_render_ring_flush; - engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT | - GT_RENDER_PIPECTL_NOTIFY_INTERRUPT; } else { if (INTEL_GEN(dev_priv) < 4) engine->flush = gen2_render_ring_flush; @@ -3048,7 +3001,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) if (ret) return ret; - if (INTEL_GEN(dev_priv) >= 5) { + if (INTEL_GEN(dev_priv) >= 6) { ret = intel_init_pipe_control(engine, 4096); if (ret) return ret; -- cgit v1.2.3 From 7ec2c73b1dbe1cd83c52e4a386b2070331c5414c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:22 +0100 Subject: drm/i915: Check the CPU cached value in HWS of seqno after waking the waiter If we have multiple waiters, we may find that many complete on the same wake up. If we first inspect the seqno from the CPU cache, we may reduce the number of heavyweight coherent seqno reads we require. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-13-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5a1e8e056ee5..ee04bd40a41a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3988,6 +3988,12 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) { struct intel_engine_cs *engine = req->engine; + /* Before we do the heavier coherent read of the seqno, + * check the value (hopefully) in the CPU cacheline. + */ + if (i915_gem_request_completed(req)) + return true; + /* Ensure our read of the seqno is coherent so that we * do not "miss an interrupt" (i.e. if this is the last * request and the seqno write from the GPU is not visible @@ -3999,11 +4005,11 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) * but it is easier and safer to do it every time the waiter * is woken. */ - if (engine->irq_seqno_barrier) + if (engine->irq_seqno_barrier) { engine->irq_seqno_barrier(engine); - - if (i915_gem_request_completed(req)) - return true; + if (i915_gem_request_completed(req)) + return true; + } /* We need to check whether any gpu reset happened in between * the request being submitted and now. If a reset has occurred, -- cgit v1.2.3 From 3d5564e91025bd17d93d0a23ebf8e22309652591 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:23 +0100 Subject: drm/i915: Only apply one barrier after a breadcrumb interrupt is posted If we flag the seqno as potentially stale upon receiving an interrupt, we can use that information to reduce the frequency that we apply the heavyweight coherent seqno read (i.e. if we wake up a chain of waiters). v2: Use cmpxchg to replace READ_ONCE/WRITE_ONCE for more explicit control of the ordering wrt to interrupt generation and interrupt checking in the bottom-half. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-14-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 15 ++++++++++++++- drivers/gpu/drm/i915/i915_irq.c | 1 + drivers/gpu/drm/i915/intel_breadcrumbs.c | 16 ++++++++++------ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ee04bd40a41a..21181a6ec0b0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -4005,7 +4005,20 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) * but it is easier and safer to do it every time the waiter * is woken. */ - if (engine->irq_seqno_barrier) { + if (engine->irq_seqno_barrier && + cmpxchg_relaxed(&engine->irq_posted, 1, 0)) { + /* The ordering of irq_posted versus applying the barrier + * is crucial. The clearing of the current irq_posted must + * be visible before we perform the barrier operation, + * such that if a subsequent interrupt arrives, irq_posted + * is reasserted and our task rewoken (which causes us to + * do another __i915_request_irq_complete() immediately + * and reapply the barrier). Conversely, if the clear + * occurs after the barrier, then an interrupt that arrived + * whilst we waited on the barrier would not trigger a + * barrier on the next pass, and the read may not see the + * seqno update. + */ engine->irq_seqno_barrier(engine); if (i915_gem_request_completed(req)) return true; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index be7f0b9b27e0..7724bae27bcf 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -976,6 +976,7 @@ static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) static void notify_ring(struct intel_engine_cs *engine) { + smp_store_mb(engine->irq_posted, true); if (intel_engine_wakeup(engine)) { trace_i915_gem_request_notify(engine); engine->user_interrupts++; diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 7cdb02d18c1f..85ef6c0e2913 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -43,12 +43,18 @@ static void intel_breadcrumbs_fake_irq(unsigned long data) static void irq_enable(struct intel_engine_cs *engine) { + /* Enabling the IRQ may miss the generation of the interrupt, but + * we still need to force the barrier before reading the seqno, + * just in case. + */ + engine->irq_posted = true; WARN_ON(!engine->irq_get(engine)); } static void irq_disable(struct intel_engine_cs *engine) { engine->irq_put(engine); + engine->irq_posted = false; } static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) @@ -56,7 +62,6 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) struct intel_engine_cs *engine = container_of(b, struct intel_engine_cs, breadcrumbs); struct drm_i915_private *i915 = engine->i915; - bool irq_posted = false; assert_spin_locked(&b->lock); if (b->rpm_wakelock) @@ -72,10 +77,8 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) /* No interrupts? Kick the waiter every jiffie! */ if (intel_irqs_enabled(i915)) { - if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings)) { + if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings)) irq_enable(engine); - irq_posted = true; - } b->irq_enabled = true; } @@ -83,7 +86,7 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) test_bit(engine->id, &i915->gpu_error.missed_irq_rings)) mod_timer(&b->fake_irq, jiffies + 1); - return irq_posted; + return engine->irq_posted; } static void __intel_breadcrumbs_disable_irq(struct intel_breadcrumbs *b) @@ -207,7 +210,8 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, * in case the seqno passed. */ __intel_breadcrumbs_enable_irq(b); - wake_up_process(to_wait(next)->tsk); + if (READ_ONCE(engine->irq_posted)) + wake_up_process(to_wait(next)->tsk); } do { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index ad86686e57f0..fcc348376080 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -185,6 +185,7 @@ struct intel_engine_cs { struct i915_ctx_workarounds wa_ctx; unsigned irq_refcount; /* protected by dev_priv->irq_lock */ + bool irq_posted; u32 irq_enable_mask; /* bitmask to enable ring interrupt */ struct drm_i915_gem_request *trace_irq_req; bool __must_check (*irq_get)(struct intel_engine_cs *ring); -- cgit v1.2.3 From 1137fa8615e1c45cc79c7c6ff06704cd1702bcfd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:24 +0100 Subject: drm/i915: Stop setting wraparound seqno on initialisation We have testcases to ensure that seqno wraparound works fine, so we can forgo forcing everyone to encounter seqno wraparound during early uptime. seqno wraparound incurs a full GPU stall so not forcing it will eliminate one jitter from the early system. Using the testcases, we have very deterministic testing which given how difficult it would be to debug an issue (GPU hang) stemming from a wraparound using pure postmortem analysis I see no value in forcing a wrap during boot. Advancing the global next_seqno after a GPU reset is equally pointless. References? https://bugs.freedesktop.org/show_bug.cgi?id=95023 Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-15-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2aef737fa761..4875c92cc64c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5119,12 +5119,6 @@ i915_gem_init_hw(struct drm_device *dev) if (ret) goto out; - /* - * Increment the next seqno by 0x100 so we have a visible break - * on re-initialisation - */ - ret = i915_gem_set_seqno(dev, dev_priv->next_seqno+0x100); - out: intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); return ret; @@ -5267,14 +5261,6 @@ i915_gem_load_init(struct drm_device *dev) dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; - /* - * Set initial sequence number for requests. - * Using this number allows the wraparound to happen early, - * catching any obvious problems. - */ - dev_priv->next_seqno = ((u32)~0 - 0x1100); - dev_priv->last_seqno = ((u32)~0 - 0x1101); - INIT_LIST_HEAD(&dev_priv->mm.fence_list); init_waitqueue_head(&dev_priv->pending_flip_queue); -- cgit v1.2.3 From c81d46138da658b6a4edc53d5d9aaf62d56d764b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:25 +0100 Subject: drm/i915: Convert trace-irq to the breadcrumb waiter If we convert the tracing over from direct use of ring->irq_get() and over to the breadcrumb infrastructure, we only have a single user of the ring->irq_get and so we will be able to simplify the driver routines (eliminating the redundant validation and irq refcounting). Process context is preferred over softirq (or even hardirq) for a couple of reasons: - we already utilize process context to have fast wakeup of a single client (i.e. the client waiting for the GPU inspects the seqno for itself following an interrupt to avoid the overhead of a context switch before it returns to userspace) - engine->irq_seqno() is not suitable for use from an softirq/hardirq context as we may require long waits (100-250us) to ensure the seqno write is posted before we read it from the CPU A signaling framework is a requirement for enabling dma-fences. v2: Move to a signaling framework based upon the waiter. v3: Track the first-signal to avoid having to walk the rbtree everytime. v4: Mark the signaler thread as RT priority to reduce latency in the indirect wakeups. v5: Make failure to allocate the thread fatal. v6: Rename kthreads to i915/signal:%u Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-16-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 8 -- drivers/gpu/drm/i915/i915_gem.c | 9 +- drivers/gpu/drm/i915/i915_trace.h | 2 +- drivers/gpu/drm/i915/intel_breadcrumbs.c | 194 ++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_ringbuffer.h | 8 +- 5 files changed, 203 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 21181a6ec0b0..ed4116f9d793 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3976,14 +3976,6 @@ wait_remaining_ms_from_jiffies(unsigned long timestamp_jiffies, int to_wait_ms) schedule_timeout_uninterruptible(remaining_jiffies); } } - -static inline void i915_trace_irq_get(struct intel_engine_cs *engine, - struct drm_i915_gem_request *req) -{ - if (engine->trace_irq_req == NULL && engine->irq_get(engine)) - i915_gem_request_assign(&engine->trace_irq_req, req); -} - static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) { struct intel_engine_cs *engine = req->engine; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4875c92cc64c..f21657f8c102 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2755,7 +2755,8 @@ i915_gem_init_seqno(struct drm_i915_private *dev_priv, u32 seqno) /* If the seqno wraps around, we need to clear the breadcrumb rbtree */ if (!i915_seqno_passed(seqno, dev_priv->next_seqno)) { - while (intel_kick_waiters(dev_priv)) + while (intel_kick_waiters(dev_priv) || + intel_kick_signalers(dev_priv)) yield(); } @@ -3219,12 +3220,6 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *engine) i915_gem_object_retire__read(obj, engine->id); } - if (unlikely(engine->trace_irq_req && - i915_gem_request_completed(engine->trace_irq_req))) { - engine->irq_put(engine); - i915_gem_request_assign(&engine->trace_irq_req, NULL); - } - WARN_ON(i915_verify_lists(engine->dev)); } diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 3d13fde95fdf..f59cf07184ae 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -490,7 +490,7 @@ TRACE_EVENT(i915_gem_ring_dispatch, __entry->ring = req->engine->id; __entry->seqno = req->seqno; __entry->flags = flags; - i915_trace_irq_get(req->engine, req); + intel_engine_enable_signaling(req); ), TP_printk("dev=%u, ring=%u, seqno=%u, flags=%x", diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 85ef6c0e2913..fa1e957f74e3 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -22,6 +22,8 @@ * */ +#include + #include "i915_drv.h" static void intel_breadcrumbs_fake_irq(unsigned long data) @@ -257,6 +259,15 @@ static inline bool chain_wakeup(struct rb_node *rb, int priority) return rb && to_wait(rb)->tsk->prio <= priority; } +static inline int wakeup_priority(struct intel_breadcrumbs *b, + struct task_struct *tsk) +{ + if (tsk == b->signaler) + return INT_MIN; + else + return tsk->prio; +} + void intel_engine_remove_wait(struct intel_engine_cs *engine, struct intel_wait *wait) { @@ -275,8 +286,8 @@ void intel_engine_remove_wait(struct intel_engine_cs *engine, goto out_unlock; if (b->first_wait == wait) { + const int priority = wakeup_priority(b, wait->tsk); struct rb_node *next; - const int priority = wait->tsk->prio; GEM_BUG_ON(b->tasklet != wait->tsk); @@ -345,15 +356,178 @@ out_unlock: spin_unlock(&b->lock); } +struct signal { + struct rb_node node; + struct intel_wait wait; + struct drm_i915_gem_request *request; +}; + +static bool signal_complete(struct signal *signal) +{ + if (!signal) + 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(&signal->wait)) + return true; + + /* 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(signal->request)) + return true; + + return false; +} + +static struct signal *to_signal(struct rb_node *rb) +{ + return container_of(rb, struct signal, node); +} + +static void signaler_set_rtpriority(void) +{ + struct sched_param param = { .sched_priority = 1 }; + + sched_setscheduler_nocheck(current, SCHED_FIFO, ¶m); +} + +static int intel_breadcrumbs_signaler(void *arg) +{ + struct intel_engine_cs *engine = arg; + struct intel_breadcrumbs *b = &engine->breadcrumbs; + struct signal *signal; + + /* Install ourselves with high priority to reduce signalling latency */ + signaler_set_rtpriority(); + + do { + set_current_state(TASK_INTERRUPTIBLE); + + /* We are either woken up by the interrupt bottom-half, + * or by a client adding a new signaller. In both cases, + * the GPU seqno may have advanced beyond our oldest signal. + * If it has, propagate the signal, remove the waiter and + * check again with the next oldest signal. Otherwise we + * need to wait for a new interrupt from the GPU or for + * a new client. + */ + signal = READ_ONCE(b->first_signal); + if (signal_complete(signal)) { + /* Wake up all other completed waiters and select the + * next bottom-half for the next user interrupt. + */ + intel_engine_remove_wait(engine, &signal->wait); + + i915_gem_request_unreference(signal->request); + + /* Find the next oldest signal. Note that as we have + * not been holding the lock, another client may + * have installed an even older signal than the one + * we just completed - so double check we are still + * the oldest before picking the next one. + */ + spin_lock(&b->lock); + if (signal == b->first_signal) + b->first_signal = rb_next(&signal->node); + rb_erase(&signal->node, &b->signals); + spin_unlock(&b->lock); + + kfree(signal); + } else { + if (kthread_should_stop()) + break; + + schedule(); + } + } while (1); + __set_current_state(TASK_RUNNING); + + return 0; +} + +int intel_engine_enable_signaling(struct drm_i915_gem_request *request) +{ + struct intel_engine_cs *engine = request->engine; + struct intel_breadcrumbs *b = &engine->breadcrumbs; + struct rb_node *parent, **p; + struct signal *signal; + bool first, wakeup; + + signal = kmalloc(sizeof(*signal), GFP_ATOMIC); + if (unlikely(!signal)) + return -ENOMEM; + + signal->wait.tsk = b->signaler; + signal->wait.seqno = request->seqno; + + signal->request = i915_gem_request_reference(request); + + /* First add ourselves into the list of waiters, but register our + * bottom-half as the signaller thread. As per usual, only the oldest + * waiter (not just signaller) is tasked as the bottom-half waking + * up all completed waiters after the user interrupt. + * + * If we are the oldest waiter, enable the irq (after which we + * must double check that the seqno did not complete). + */ + wakeup = intel_engine_add_wait(engine, &signal->wait); + + /* Now insert ourselves into the retirement ordered list of signals + * on this engine. We track the oldest seqno as that will be the + * first signal to complete. + */ + spin_lock(&b->lock); + parent = NULL; + first = true; + p = &b->signals.rb_node; + while (*p) { + parent = *p; + if (i915_seqno_passed(signal->wait.seqno, + to_signal(parent)->wait.seqno)) { + p = &parent->rb_right; + first = false; + } else { + p = &parent->rb_left; + } + } + rb_link_node(&signal->node, parent, p); + rb_insert_color(&signal->node, &b->signals); + if (first) + smp_store_mb(b->first_signal, signal); + spin_unlock(&b->lock); + + if (wakeup) + wake_up_process(b->signaler); + + return 0; +} + int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; + struct task_struct *tsk; spin_lock_init(&b->lock); setup_timer(&b->fake_irq, intel_breadcrumbs_fake_irq, (unsigned long)engine); + /* Spawn a thread to provide a common bottom-half for all signals. + * As this is an asynchronous interface we cannot steal the current + * task for handling the bottom-half to the user interrupt, therefore + * we create a thread to do the coherent seqno dance after the + * interrupt and then signal the waitqueue (via the dma-buf/fence). + */ + tsk = kthread_run(intel_breadcrumbs_signaler, engine, + "i915/signal:%d", engine->id); + if (IS_ERR(tsk)) + return PTR_ERR(tsk); + + b->signaler = tsk; + return 0; } @@ -361,6 +535,9 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; + if (!IS_ERR_OR_NULL(b->signaler)) + kthread_stop(b->signaler); + del_timer_sync(&b->fake_irq); } @@ -382,3 +559,18 @@ unsigned int intel_kick_waiters(struct drm_i915_private *i915) return mask; } + +unsigned int intel_kick_signalers(struct drm_i915_private *i915) +{ + struct intel_engine_cs *engine; + unsigned int mask = 0; + + for_each_engine(engine, i915) { + if (unlikely(READ_ONCE(engine->breadcrumbs.first_signal))) { + wake_up_process(engine->breadcrumbs.signaler); + mask |= intel_engine_flag(engine); + } + } + + return mask; +} diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index fcc348376080..1d4a23681285 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -129,6 +129,8 @@ struct i915_ctx_workarounds { struct drm_i915_gem_object *obj; }; +struct drm_i915_gem_request; + struct intel_engine_cs { struct drm_i915_private *i915; const char *name; @@ -167,8 +169,11 @@ struct intel_engine_cs { struct intel_breadcrumbs { spinlock_t lock; /* protects the lists of requests */ struct rb_root waiters; /* sorted by retirement, priority */ + struct rb_root signals; /* sorted by retirement */ struct intel_wait *first_wait; /* oldest waiter by retirement */ struct task_struct *tasklet; /* bh for user interrupts */ + struct task_struct *signaler; /* used for fence signalling */ + void *first_signal; struct timer_list fake_irq; /* used after a missed interrupt */ bool irq_enabled; bool rpm_wakelock; @@ -187,7 +192,6 @@ struct intel_engine_cs { unsigned irq_refcount; /* protected by dev_priv->irq_lock */ bool irq_posted; u32 irq_enable_mask; /* bitmask to enable ring interrupt */ - struct drm_i915_gem_request *trace_irq_req; bool __must_check (*irq_get)(struct intel_engine_cs *ring); void (*irq_put)(struct intel_engine_cs *ring); @@ -532,6 +536,7 @@ bool intel_engine_add_wait(struct intel_engine_cs *engine, struct intel_wait *wait); void intel_engine_remove_wait(struct intel_engine_cs *engine, struct intel_wait *wait); +int intel_engine_enable_signaling(struct drm_i915_gem_request *request); static inline bool intel_engine_has_waiter(struct intel_engine_cs *engine) { @@ -558,5 +563,6 @@ static inline bool intel_engine_wakeup(struct intel_engine_cs *engine) void intel_engine_enable_fake_irq(struct intel_engine_cs *engine); void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine); unsigned int intel_kick_waiters(struct drm_i915_private *i915); +unsigned int intel_kick_signalers(struct drm_i915_private *i915); #endif /* _INTEL_RINGBUFFER_H_ */ -- cgit v1.2.3 From b3850855f480a34bf528f78e1ff693739b3aa98c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:26 +0100 Subject: drm/i915: Embed signaling node into the GEM request Under the assumption that enabling signaling will be a frequent operation, lets preallocate our attachments for signaling inside the (rather large) request struct (and so benefiting from the slab cache). v2: Convert from void * to more meaningful names and types. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-17-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_breadcrumbs.c | 76 ++++++++++++++++---------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 9 +++- 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ed4116f9d793..0dcc43d2994b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2380,6 +2380,7 @@ struct drm_i915_gem_request { /** On Which ring this request was generated */ struct drm_i915_private *i915; struct intel_engine_cs *engine; + struct intel_signal_node signaling; /** GEM sequence number associated with the previous request, * when the HWS breadcrumb is equal to this the GPU is processing diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index fa1e957f74e3..f20ccacde81e 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -356,35 +356,29 @@ out_unlock: spin_unlock(&b->lock); } -struct signal { - struct rb_node node; - struct intel_wait wait; - struct drm_i915_gem_request *request; -}; - -static bool signal_complete(struct signal *signal) +static bool signal_complete(struct drm_i915_gem_request *request) { - if (!signal) + 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(&signal->wait)) + if (intel_wait_complete(&request->signaling.wait)) return true; /* 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(signal->request)) + if (__i915_request_irq_complete(request)) return true; return false; } -static struct signal *to_signal(struct rb_node *rb) +static struct drm_i915_gem_request *to_signaler(struct rb_node *rb) { - return container_of(rb, struct signal, node); + return container_of(rb, struct drm_i915_gem_request, signaling.node); } static void signaler_set_rtpriority(void) @@ -398,7 +392,7 @@ static int intel_breadcrumbs_signaler(void *arg) { struct intel_engine_cs *engine = arg; struct intel_breadcrumbs *b = &engine->breadcrumbs; - struct signal *signal; + struct drm_i915_gem_request *request; /* Install ourselves with high priority to reduce signalling latency */ signaler_set_rtpriority(); @@ -414,14 +408,13 @@ static int intel_breadcrumbs_signaler(void *arg) * need to wait for a new interrupt from the GPU or for * a new client. */ - signal = READ_ONCE(b->first_signal); - if (signal_complete(signal)) { + request = READ_ONCE(b->first_signal); + if (signal_complete(request)) { /* Wake up all other completed waiters and select the * next bottom-half for the next user interrupt. */ - intel_engine_remove_wait(engine, &signal->wait); - - i915_gem_request_unreference(signal->request); + intel_engine_remove_wait(engine, + &request->signaling.wait); /* Find the next oldest signal. Note that as we have * not been holding the lock, another client may @@ -430,12 +423,15 @@ static int intel_breadcrumbs_signaler(void *arg) * the oldest before picking the next one. */ spin_lock(&b->lock); - if (signal == b->first_signal) - b->first_signal = rb_next(&signal->node); - rb_erase(&signal->node, &b->signals); + if (request == b->first_signal) { + struct rb_node *rb = + rb_next(&request->signaling.node); + b->first_signal = rb ? to_signaler(rb) : NULL; + } + rb_erase(&request->signaling.node, &b->signals); spin_unlock(&b->lock); - kfree(signal); + i915_gem_request_unreference(request); } else { if (kthread_should_stop()) break; @@ -448,22 +444,25 @@ static int intel_breadcrumbs_signaler(void *arg) return 0; } -int intel_engine_enable_signaling(struct drm_i915_gem_request *request) +void intel_engine_enable_signaling(struct drm_i915_gem_request *request) { struct intel_engine_cs *engine = request->engine; struct intel_breadcrumbs *b = &engine->breadcrumbs; struct rb_node *parent, **p; - struct signal *signal; bool first, wakeup; - signal = kmalloc(sizeof(*signal), GFP_ATOMIC); - if (unlikely(!signal)) - return -ENOMEM; + if (unlikely(READ_ONCE(request->signaling.wait.tsk))) + return; - signal->wait.tsk = b->signaler; - signal->wait.seqno = request->seqno; + spin_lock(&b->lock); + if (unlikely(request->signaling.wait.tsk)) { + wakeup = false; + goto unlock; + } - signal->request = i915_gem_request_reference(request); + request->signaling.wait.tsk = b->signaler; + request->signaling.wait.seqno = request->seqno; + i915_gem_request_reference(request); /* First add ourselves into the list of waiters, but register our * bottom-half as the signaller thread. As per usual, only the oldest @@ -473,36 +472,35 @@ int intel_engine_enable_signaling(struct drm_i915_gem_request *request) * If we are the oldest waiter, enable the irq (after which we * must double check that the seqno did not complete). */ - wakeup = intel_engine_add_wait(engine, &signal->wait); + wakeup = __intel_engine_add_wait(engine, &request->signaling.wait); /* Now insert ourselves into the retirement ordered list of signals * on this engine. We track the oldest seqno as that will be the * first signal to complete. */ - spin_lock(&b->lock); parent = NULL; first = true; p = &b->signals.rb_node; while (*p) { parent = *p; - if (i915_seqno_passed(signal->wait.seqno, - to_signal(parent)->wait.seqno)) { + if (i915_seqno_passed(request->seqno, + to_signaler(parent)->seqno)) { p = &parent->rb_right; first = false; } else { p = &parent->rb_left; } } - rb_link_node(&signal->node, parent, p); - rb_insert_color(&signal->node, &b->signals); + rb_link_node(&request->signaling.node, parent, p); + rb_insert_color(&request->signaling.node, &b->signals); if (first) - smp_store_mb(b->first_signal, signal); + smp_store_mb(b->first_signal, request); + +unlock: spin_unlock(&b->lock); if (wakeup) wake_up_process(b->signaler); - - return 0; } int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 1d4a23681285..cac838384588 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -173,7 +173,7 @@ struct intel_engine_cs { struct intel_wait *first_wait; /* oldest waiter by retirement */ struct task_struct *tasklet; /* bh for user interrupts */ struct task_struct *signaler; /* used for fence signalling */ - void *first_signal; + struct drm_i915_gem_request *first_signal; struct timer_list fake_irq; /* used after a missed interrupt */ bool irq_enabled; bool rpm_wakelock; @@ -519,6 +519,11 @@ struct intel_wait { u32 seqno; }; +struct intel_signal_node { + struct rb_node node; + struct intel_wait wait; +}; + int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine); static inline void intel_wait_init(struct intel_wait *wait, u32 seqno) @@ -536,7 +541,7 @@ bool intel_engine_add_wait(struct intel_engine_cs *engine, struct intel_wait *wait); void intel_engine_remove_wait(struct intel_engine_cs *engine, struct intel_wait *wait); -int intel_engine_enable_signaling(struct drm_i915_gem_request *request); +void intel_engine_enable_signaling(struct drm_i915_gem_request *request); static inline bool intel_engine_has_waiter(struct intel_engine_cs *engine) { -- cgit v1.2.3 From 31bb59cc01fda94e55eca7304e0e745908c3bec6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:27 +0100 Subject: drm/i915: Move the get/put irq locking into the caller With only a single callsite for intel_engine_cs->irq_get and ->irq_put, we can reduce the code size by moving the common preamble into the caller, and we can also eliminate the reference counting. For completeness, as we are no longer doing reference counting on irq, rename the get/put vfunctions to enable/disable respectively and are able to review the use of posting reads. We only require the serialisation with hardware when enabling the interrupt (i.e. so we cannot miss an interrupt by going to sleep before the hardware truly enables it). Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-18-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 8 +- drivers/gpu/drm/i915/intel_breadcrumbs.c | 10 +- drivers/gpu/drm/i915/intel_lrc.c | 34 ++--- drivers/gpu/drm/i915/intel_ringbuffer.c | 237 +++++++++---------------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 5 +- 5 files changed, 92 insertions(+), 202 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7724bae27bcf..be25b7bdacfe 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -259,12 +259,12 @@ static void ilk_update_gt_irq(struct drm_i915_private *dev_priv, dev_priv->gt_irq_mask &= ~interrupt_mask; dev_priv->gt_irq_mask |= (~enabled_irq_mask & interrupt_mask); I915_WRITE(GTIMR, dev_priv->gt_irq_mask); - POSTING_READ(GTIMR); } void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) { ilk_update_gt_irq(dev_priv, mask, mask); + POSTING_READ_FW(GTIMR); } void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask) @@ -2819,9 +2819,9 @@ ring_idle(struct intel_engine_cs *engine, u32 seqno) } static bool -ipehr_is_semaphore_wait(struct drm_i915_private *dev_priv, u32 ipehr) +ipehr_is_semaphore_wait(struct intel_engine_cs *engine, u32 ipehr) { - if (INTEL_GEN(dev_priv) >= 8) { + if (INTEL_GEN(engine->i915) >= 8) { return (ipehr >> 23) == 0x1c; } else { ipehr &= ~MI_SEMAPHORE_SYNC_MASK; @@ -2892,7 +2892,7 @@ semaphore_waits_for(struct intel_engine_cs *engine, u32 *seqno) return NULL; ipehr = I915_READ(RING_IPEHR(engine->mmio_base)); - if (!ipehr_is_semaphore_wait(engine->i915, ipehr)) + if (!ipehr_is_semaphore_wait(engine, ipehr)) return NULL; /* diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index f20ccacde81e..009d6e121767 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -50,12 +50,18 @@ static void irq_enable(struct intel_engine_cs *engine) * just in case. */ engine->irq_posted = true; - WARN_ON(!engine->irq_get(engine)); + + spin_lock_irq(&engine->i915->irq_lock); + engine->irq_enable(engine); + spin_unlock_irq(&engine->i915->irq_lock); } static void irq_disable(struct intel_engine_cs *engine) { - engine->irq_put(engine); + spin_lock_irq(&engine->i915->irq_lock); + engine->irq_disable(engine); + spin_unlock_irq(&engine->i915->irq_lock); + engine->irq_posted = false; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f1a01137334c..380175149916 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1617,36 +1617,18 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req, return 0; } -static bool gen8_logical_ring_get_irq(struct intel_engine_cs *engine) +static void gen8_logical_ring_enable_irq(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - - if (WARN_ON(!intel_irqs_enabled(dev_priv))) - return false; - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (engine->irq_refcount++ == 0) { - I915_WRITE_IMR(engine, - ~(engine->irq_enable_mask | engine->irq_keep_mask)); - POSTING_READ(RING_IMR(engine->mmio_base)); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - - return true; + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | engine->irq_keep_mask)); + POSTING_READ_FW(RING_IMR(engine->mmio_base)); } -static void gen8_logical_ring_put_irq(struct intel_engine_cs *engine) +static void gen8_logical_ring_disable_irq(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--engine->irq_refcount == 0) { - I915_WRITE_IMR(engine, ~engine->irq_keep_mask); - POSTING_READ(RING_IMR(engine->mmio_base)); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + I915_WRITE_IMR(engine, ~engine->irq_keep_mask); } static int gen8_emit_flush(struct drm_i915_gem_request *request, @@ -1966,8 +1948,8 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine) engine->init_hw = gen8_init_common_ring; engine->emit_request = gen8_emit_request; engine->emit_flush = gen8_emit_flush; - engine->irq_get = gen8_logical_ring_get_irq; - engine->irq_put = gen8_logical_ring_put_irq; + engine->irq_enable = gen8_logical_ring_enable_irq; + engine->irq_disable = gen8_logical_ring_disable_irq; engine->emit_bb_start = gen8_emit_bb_start; if (IS_BXT_REVID(engine->i915, 0, BXT_REVID_A1)) engine->irq_seqno_barrier = bxt_a_seqno_barrier; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3bd598673d88..994f7616a58b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1636,103 +1636,54 @@ gen6_seqno_barrier(struct intel_engine_cs *engine) spin_unlock_irq(&dev_priv->uncore.lock); } -static bool -gen5_ring_get_irq(struct intel_engine_cs *engine) +static void +gen5_irq_enable(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - - if (WARN_ON(!intel_irqs_enabled(dev_priv))) - return false; - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (engine->irq_refcount++ == 0) - gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask); - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - - return true; + gen5_enable_gt_irq(engine->i915, engine->irq_enable_mask); } static void -gen5_ring_put_irq(struct intel_engine_cs *engine) +gen5_irq_disable(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--engine->irq_refcount == 0) - gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask); - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + gen5_disable_gt_irq(engine->i915, engine->irq_enable_mask); } -static bool -i9xx_ring_get_irq(struct intel_engine_cs *engine) +static void +i9xx_irq_enable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - - if (!intel_irqs_enabled(dev_priv)) - return false; - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (engine->irq_refcount++ == 0) { - dev_priv->irq_mask &= ~engine->irq_enable_mask; - I915_WRITE(IMR, dev_priv->irq_mask); - POSTING_READ(IMR); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - return true; + dev_priv->irq_mask &= ~engine->irq_enable_mask; + I915_WRITE(IMR, dev_priv->irq_mask); + POSTING_READ_FW(RING_IMR(engine->mmio_base)); } static void -i9xx_ring_put_irq(struct intel_engine_cs *engine) +i9xx_irq_disable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--engine->irq_refcount == 0) { - dev_priv->irq_mask |= engine->irq_enable_mask; - I915_WRITE(IMR, dev_priv->irq_mask); - POSTING_READ(IMR); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + dev_priv->irq_mask |= engine->irq_enable_mask; + I915_WRITE(IMR, dev_priv->irq_mask); } -static bool -i8xx_ring_get_irq(struct intel_engine_cs *engine) +static void +i8xx_irq_enable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - if (!intel_irqs_enabled(dev_priv)) - return false; - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (engine->irq_refcount++ == 0) { - dev_priv->irq_mask &= ~engine->irq_enable_mask; - I915_WRITE16(IMR, dev_priv->irq_mask); - POSTING_READ16(IMR); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - - return true; + dev_priv->irq_mask &= ~engine->irq_enable_mask; + I915_WRITE16(IMR, dev_priv->irq_mask); + POSTING_READ16(RING_IMR(engine->mmio_base)); } static void -i8xx_ring_put_irq(struct intel_engine_cs *engine) +i8xx_irq_disable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--engine->irq_refcount == 0) { - dev_priv->irq_mask |= engine->irq_enable_mask; - I915_WRITE16(IMR, dev_priv->irq_mask); - POSTING_READ16(IMR); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + dev_priv->irq_mask |= engine->irq_enable_mask; + I915_WRITE16(IMR, dev_priv->irq_mask); } static int @@ -1773,122 +1724,74 @@ i9xx_add_request(struct drm_i915_gem_request *req) return 0; } -static bool -gen6_ring_get_irq(struct intel_engine_cs *engine) +static void +gen6_irq_enable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - - if (WARN_ON(!intel_irqs_enabled(dev_priv))) - return false; - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (engine->irq_refcount++ == 0) { - if (HAS_L3_DPF(dev_priv) && engine->id == RCS) - I915_WRITE_IMR(engine, - ~(engine->irq_enable_mask | - GT_PARITY_ERROR(dev_priv))); - else - I915_WRITE_IMR(engine, ~engine->irq_enable_mask); - gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - - return true; + if (HAS_L3_DPF(dev_priv) && engine->id == RCS) + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | + GT_PARITY_ERROR(dev_priv))); + else + I915_WRITE_IMR(engine, ~engine->irq_enable_mask); + gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask); } static void -gen6_ring_put_irq(struct intel_engine_cs *engine) +gen6_irq_disable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--engine->irq_refcount == 0) { - if (HAS_L3_DPF(dev_priv) && engine->id == RCS) - I915_WRITE_IMR(engine, ~GT_PARITY_ERROR(dev_priv)); - else - I915_WRITE_IMR(engine, ~0); - gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + if (HAS_L3_DPF(dev_priv) && engine->id == RCS) + I915_WRITE_IMR(engine, ~GT_PARITY_ERROR(dev_priv)); + else + I915_WRITE_IMR(engine, ~0); + gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask); } -static bool -hsw_vebox_get_irq(struct intel_engine_cs *engine) +static void +hsw_vebox_irq_enable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - - if (WARN_ON(!intel_irqs_enabled(dev_priv))) - return false; - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (engine->irq_refcount++ == 0) { - I915_WRITE_IMR(engine, ~engine->irq_enable_mask); - gen6_enable_pm_irq(dev_priv, engine->irq_enable_mask); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - - return true; + I915_WRITE_IMR(engine, ~engine->irq_enable_mask); + gen6_enable_pm_irq(dev_priv, engine->irq_enable_mask); } static void -hsw_vebox_put_irq(struct intel_engine_cs *engine) +hsw_vebox_irq_disable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--engine->irq_refcount == 0) { - I915_WRITE_IMR(engine, ~0); - gen6_disable_pm_irq(dev_priv, engine->irq_enable_mask); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + I915_WRITE_IMR(engine, ~0); + gen6_disable_pm_irq(dev_priv, engine->irq_enable_mask); } -static bool -gen8_ring_get_irq(struct intel_engine_cs *engine) +static void +gen8_irq_enable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - if (WARN_ON(!intel_irqs_enabled(dev_priv))) - return false; - - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (engine->irq_refcount++ == 0) { - if (HAS_L3_DPF(dev_priv) && engine->id == RCS) { - I915_WRITE_IMR(engine, - ~(engine->irq_enable_mask | - GT_RENDER_L3_PARITY_ERROR_INTERRUPT)); - } else { - I915_WRITE_IMR(engine, ~engine->irq_enable_mask); - } - POSTING_READ(RING_IMR(engine->mmio_base)); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); - - return true; + if (HAS_L3_DPF(dev_priv) && engine->id == RCS) + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | + GT_RENDER_L3_PARITY_ERROR_INTERRUPT)); + else + I915_WRITE_IMR(engine, ~engine->irq_enable_mask); + POSTING_READ_FW(RING_IMR(engine->mmio_base)); } static void -gen8_ring_put_irq(struct intel_engine_cs *engine) +gen8_irq_disable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - unsigned long flags; - spin_lock_irqsave(&dev_priv->irq_lock, flags); - if (--engine->irq_refcount == 0) { - if (HAS_L3_DPF(dev_priv) && engine->id == RCS) { - I915_WRITE_IMR(engine, - ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); - } else { - I915_WRITE_IMR(engine, ~0); - } - POSTING_READ(RING_IMR(engine->mmio_base)); - } - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + if (HAS_L3_DPF(dev_priv) && engine->id == RCS) + I915_WRITE_IMR(engine, + ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); + else + I915_WRITE_IMR(engine, ~0); } static int @@ -2909,23 +2812,23 @@ static void intel_ring_init_irq(struct drm_i915_private *dev_priv, struct intel_engine_cs *engine) { if (INTEL_GEN(dev_priv) >= 8) { - engine->irq_get = gen8_ring_get_irq; - engine->irq_put = gen8_ring_put_irq; + engine->irq_enable = gen8_irq_enable; + engine->irq_disable = gen8_irq_disable; engine->irq_seqno_barrier = gen6_seqno_barrier; } else if (INTEL_GEN(dev_priv) >= 6) { - engine->irq_get = gen6_ring_get_irq; - engine->irq_put = gen6_ring_put_irq; + engine->irq_enable = gen6_irq_enable; + engine->irq_disable = gen6_irq_disable; engine->irq_seqno_barrier = gen6_seqno_barrier; } else if (INTEL_GEN(dev_priv) >= 5) { - engine->irq_get = gen5_ring_get_irq; - engine->irq_put = gen5_ring_put_irq; + engine->irq_enable = gen5_irq_enable; + engine->irq_disable = gen5_irq_disable; engine->irq_seqno_barrier = gen5_seqno_barrier; } else if (INTEL_GEN(dev_priv) >= 3) { - engine->irq_get = i9xx_ring_get_irq; - engine->irq_put = i9xx_ring_put_irq; + engine->irq_enable = i9xx_irq_enable; + engine->irq_disable = i9xx_irq_disable; } else { - engine->irq_get = i8xx_ring_get_irq; - engine->irq_put = i8xx_ring_put_irq; + engine->irq_enable = i8xx_irq_enable; + engine->irq_disable = i8xx_irq_disable; } } @@ -3115,8 +3018,8 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; } else { engine->irq_enable_mask = PM_VEBOX_USER_INTERRUPT; - engine->irq_get = hsw_vebox_get_irq; - engine->irq_put = hsw_vebox_put_irq; + engine->irq_enable = hsw_vebox_irq_enable; + engine->irq_disable = hsw_vebox_irq_disable; } return intel_init_ring_buffer(dev, engine); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index cac838384588..3fdf2a06e131 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -189,11 +189,10 @@ struct intel_engine_cs { struct intel_hw_status_page status_page; struct i915_ctx_workarounds wa_ctx; - unsigned irq_refcount; /* protected by dev_priv->irq_lock */ bool irq_posted; u32 irq_enable_mask; /* bitmask to enable ring interrupt */ - bool __must_check (*irq_get)(struct intel_engine_cs *ring); - void (*irq_put)(struct intel_engine_cs *ring); + void (*irq_enable)(struct intel_engine_cs *ring); + void (*irq_disable)(struct intel_engine_cs *ring); int (*init_hw)(struct intel_engine_cs *ring); -- cgit v1.2.3 From 61ff75ac20ffa6d0039f643234d0c5244070fb15 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:28 +0100 Subject: drm/i915: Simplify enabling user-interrupts with L3-remapping Borrow the idea from intel_lrc.c to precompute the mask of interrupts we wish to always enable to avoid having lots of conditionals inside the interrupt enabling. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-19-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_ringbuffer.c | 34 +++++++++++---------------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++-- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 994f7616a58b..a924a9f9eb4d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1313,8 +1313,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 (HAS_L3_DPF(dev_priv)) - I915_WRITE_IMR(engine, ~GT_PARITY_ERROR(dev_priv)); + I915_WRITE_IMR(engine, ~engine->irq_keep_mask); return init_workarounds_ring(engine); } @@ -1729,12 +1728,9 @@ gen6_irq_enable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - if (HAS_L3_DPF(dev_priv) && engine->id == RCS) - I915_WRITE_IMR(engine, - ~(engine->irq_enable_mask | - GT_PARITY_ERROR(dev_priv))); - else - I915_WRITE_IMR(engine, ~engine->irq_enable_mask); + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | + engine->irq_keep_mask)); gen5_enable_gt_irq(dev_priv, engine->irq_enable_mask); } @@ -1743,10 +1739,7 @@ gen6_irq_disable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - if (HAS_L3_DPF(dev_priv) && engine->id == RCS) - I915_WRITE_IMR(engine, ~GT_PARITY_ERROR(dev_priv)); - else - I915_WRITE_IMR(engine, ~0); + I915_WRITE_IMR(engine, ~engine->irq_keep_mask); gen5_disable_gt_irq(dev_priv, engine->irq_enable_mask); } @@ -1773,12 +1766,9 @@ gen8_irq_enable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - if (HAS_L3_DPF(dev_priv) && engine->id == RCS) - I915_WRITE_IMR(engine, - ~(engine->irq_enable_mask | - GT_RENDER_L3_PARITY_ERROR_INTERRUPT)); - else - I915_WRITE_IMR(engine, ~engine->irq_enable_mask); + I915_WRITE_IMR(engine, + ~(engine->irq_enable_mask | + engine->irq_keep_mask)); POSTING_READ_FW(RING_IMR(engine->mmio_base)); } @@ -1787,11 +1777,7 @@ gen8_irq_disable(struct intel_engine_cs *engine) { struct drm_i915_private *dev_priv = engine->i915; - if (HAS_L3_DPF(dev_priv) && engine->id == RCS) - I915_WRITE_IMR(engine, - ~GT_RENDER_L3_PARITY_ERROR_INTERRUPT); - else - I915_WRITE_IMR(engine, ~0); + I915_WRITE_IMR(engine, ~engine->irq_keep_mask); } static int @@ -2872,6 +2858,8 @@ int intel_init_render_ring_buffer(struct drm_device *dev) intel_ring_default_vfuncs(dev_priv, engine); engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT; + if (HAS_L3_DPF(dev_priv)) + engine->irq_keep_mask = GT_RENDER_L3_PARITY_ERROR_INTERRUPT; if (INTEL_GEN(dev_priv) >= 8) { engine->init_context = intel_rcs_ctx_init; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3fdf2a06e131..41cc9f395a9c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -190,7 +190,8 @@ struct intel_engine_cs { struct i915_ctx_workarounds wa_ctx; bool irq_posted; - u32 irq_enable_mask; /* bitmask to enable ring interrupt */ + u32 irq_keep_mask; /* always keep these interrupts */ + u32 irq_enable_mask; /* bitmask to enable ring interrupt */ void (*irq_enable)(struct intel_engine_cs *ring); void (*irq_disable)(struct intel_engine_cs *ring); @@ -287,7 +288,6 @@ struct intel_engine_cs { unsigned int idle_lite_restore_wa; bool disable_lite_restore_wa; u32 ctx_desc_template; - u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */ int (*emit_request)(struct drm_i915_gem_request *request); int (*emit_flush)(struct drm_i915_gem_request *request, u32 invalidate_domains, -- cgit v1.2.3 From c5a7b5aacea23f21f2def7c175c64bedbc872202 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 Jul 2016 17:23:29 +0100 Subject: drm/i915: Remove debug noise on detecting fault-injection of missed interrupts Since the tests can and do explicitly check debugfs/i915_ring_missed_irqs for the handling of a "missed interrupt", adding it to the dmesg at INFO is just noise. When it happens for real, we still class it as an ERROR. Note that I have chose to remove it entirely because when we detect the "missed interrupt" is irrelevant and the message contains no more information than we glean from looking in debugfs. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467390209-3576-20-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index be25b7bdacfe..53d4c8088f28 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3072,9 +3072,6 @@ static unsigned kick_waiters(struct intel_engine_cs *engine) if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings)) DRM_ERROR("Hangcheck timer elapsed... %s idle\n", engine->name); - else - DRM_INFO("Fake missed irq on %s\n", - engine->name); intel_engine_enable_fake_irq(engine); } -- cgit v1.2.3 From 338d0eeaa9a7699744642720bf5adcdd5400f0a2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:35:58 +0100 Subject: drm/i915: Fix random indent in i915_drm_resume() smatch complains: drivers/gpu/drm/i915/i915_drv.c:1616 i915_drm_resume() warn: inconsistent indenting Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c9abf912249f..6fa9c0338b1b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1982,7 +1982,7 @@ static int i915_drm_resume(struct drm_device *dev) mutex_lock(&dev->struct_mutex); if (i915_gem_init_hw(dev)) { DRM_ERROR("failed to re-initialize GPU, declaring wedged!\n"); - atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter); + atomic_or(I915_WEDGED, &dev_priv->gpu_error.reset_counter); } mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From a72b562362bbcdcc2aeca20385ff88e7741bb673 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:35:59 +0100 Subject: drm/915: Fix long lines and random indent in gen6_set_rps_thresholds() smatch complains: drivers/gpu/drm/i915/intel_pm.c:4745 gen6_set_rps_thresholds() warn: inconsistent indenting Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-2-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/intel_pm.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 82c2efdcdd89..1ded2ca0f2d5 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4667,19 +4667,23 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) new_power = dev_priv->rps.power; switch (dev_priv->rps.power) { case LOW_POWER: - if (val > dev_priv->rps.efficient_freq + 1 && val > dev_priv->rps.cur_freq) + if (val > dev_priv->rps.efficient_freq + 1 && + val > dev_priv->rps.cur_freq) new_power = BETWEEN; break; case BETWEEN: - if (val <= dev_priv->rps.efficient_freq && val < dev_priv->rps.cur_freq) + if (val <= dev_priv->rps.efficient_freq && + val < dev_priv->rps.cur_freq) new_power = LOW_POWER; - else if (val >= dev_priv->rps.rp0_freq && val > dev_priv->rps.cur_freq) + else if (val >= dev_priv->rps.rp0_freq && + val > dev_priv->rps.cur_freq) new_power = HIGH_POWER; break; case HIGH_POWER: - if (val < (dev_priv->rps.rp1_freq + dev_priv->rps.rp0_freq) >> 1 && val < dev_priv->rps.cur_freq) + if (val < (dev_priv->rps.rp1_freq + dev_priv->rps.rp0_freq) >> 1 && + val < dev_priv->rps.cur_freq) new_power = BETWEEN; break; } @@ -4725,22 +4729,24 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) } I915_WRITE(GEN6_RP_UP_EI, - GT_INTERVAL_FROM_US(dev_priv, ei_up)); + GT_INTERVAL_FROM_US(dev_priv, ei_up)); I915_WRITE(GEN6_RP_UP_THRESHOLD, - GT_INTERVAL_FROM_US(dev_priv, (ei_up * threshold_up / 100))); + GT_INTERVAL_FROM_US(dev_priv, + ei_up * threshold_up / 100)); I915_WRITE(GEN6_RP_DOWN_EI, - GT_INTERVAL_FROM_US(dev_priv, ei_down)); + GT_INTERVAL_FROM_US(dev_priv, ei_down)); I915_WRITE(GEN6_RP_DOWN_THRESHOLD, - GT_INTERVAL_FROM_US(dev_priv, (ei_down * threshold_down / 100))); - - I915_WRITE(GEN6_RP_CONTROL, - GEN6_RP_MEDIA_TURBO | - GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | - GEN6_RP_ENABLE | - GEN6_RP_UP_BUSY_AVG | - GEN6_RP_DOWN_IDLE_AVG); + GT_INTERVAL_FROM_US(dev_priv, + ei_down * threshold_down / 100)); + + I915_WRITE(GEN6_RP_CONTROL, + GEN6_RP_MEDIA_TURBO | + GEN6_RP_MEDIA_HW_NORMAL_MODE | + GEN6_RP_MEDIA_IS_GFX | + GEN6_RP_ENABLE | + GEN6_RP_UP_BUSY_AVG | + GEN6_RP_DOWN_IDLE_AVG); dev_priv->rps.power = new_power; dev_priv->rps.up_threshold = threshold_up; -- cgit v1.2.3 From 25bcce94be4a733043ce8ef0fb4a5d31b2315be1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:36:00 +0100 Subject: drm/i915: Fix indentation in i915_gem_framebuffer_info() smatch complains: drivers/gpu/drm/i915/i915_debugfs.c:1390 i915_frequency_info() Function too hairy. Giving up. drivers/gpu/drm/i915/i915_debugfs.c:1985 i915_gem_framebuffer_info() warn: inconsistent indenting Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-3-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/i915_debugfs.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f5899b631c0e..abc4ae8ad498 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1982,19 +1982,19 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) return ret; #ifdef CONFIG_DRM_FBDEV_EMULATION - if (to_i915(dev)->fbdev) { - fbdev_fb = to_intel_framebuffer(to_i915(dev)->fbdev->helper.fb); - - seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", - fbdev_fb->base.width, - fbdev_fb->base.height, - fbdev_fb->base.depth, - fbdev_fb->base.bits_per_pixel, - fbdev_fb->base.modifier[0], - drm_framebuffer_read_refcount(&fbdev_fb->base)); - describe_obj(m, fbdev_fb->obj); - seq_putc(m, '\n'); - } + if (to_i915(dev)->fbdev) { + fbdev_fb = to_intel_framebuffer(to_i915(dev)->fbdev->helper.fb); + + seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ", + fbdev_fb->base.width, + fbdev_fb->base.height, + fbdev_fb->base.depth, + fbdev_fb->base.bits_per_pixel, + fbdev_fb->base.modifier[0], + drm_framebuffer_read_refcount(&fbdev_fb->base)); + describe_obj(m, fbdev_fb->obj); + seq_putc(m, '\n'); + } #endif mutex_lock(&dev->mode_config.fb_lock); -- cgit v1.2.3 From a98b7e58e93c7f937cb2283e600ed2d0a2bb74f4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:36:01 +0100 Subject: drm/i915: Fix inconsistent indenting in i915_error_state_to_str() smatch complains: drivers/gpu/drm/i915/i915_gpu_error.c:503 i915_error_state_to_str() warn: inconsistent indenting Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-4-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/i915_gpu_error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 1c15a74530cd..3a46a84fe3e3 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -500,7 +500,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, hws_page[elt+1], hws_page[elt+2], hws_page[elt+3]); - offset += 16; + offset += 16; } } -- cgit v1.2.3 From 86f40bb655ccde1d6ea2f1eaab7c1e62e9ee7742 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:36:02 +0100 Subject: drm/i915: Match bitmask size to types in intel_fb_initial_config() smatch complains of: drivers/gpu/drm/i915/intel_fbdev.c:403 intel_fb_initial_config() warn: should '1 << i' be a 64 bit type? drivers/gpu/drm/i915/intel_fbdev.c:422 intel_fb_initial_config() warn: should '1 << i' be a 64 bit type? drivers/gpu/drm/i915/intel_fbdev.c:501 intel_fb_initial_config() warn: should '1 << i' be a 64 bit type? We are prepared to iterate over a u64 but don't limit the number of connectors we try to configure to a maximum of 64. Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-5-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/intel_fbdev.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 16d73eaa46fb..224180e402be 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -362,23 +362,24 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper, bool *enabled, int width, int height) { struct drm_device *dev = fb_helper->dev; + unsigned long conn_configured, mask; + unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG); int i, j; bool *save_enabled; bool fallback = true; int num_connectors_enabled = 0; int num_connectors_detected = 0; - uint64_t conn_configured = 0, mask; int pass = 0; - save_enabled = kcalloc(fb_helper->connector_count, sizeof(bool), - GFP_KERNEL); + save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL); if (!save_enabled) return false; - memcpy(save_enabled, enabled, fb_helper->connector_count); - mask = (1 << fb_helper->connector_count) - 1; + memcpy(save_enabled, enabled, count); + mask = BIT(count) - 1; + conn_configured = 0; retry: - for (i = 0; i < fb_helper->connector_count; i++) { + for (i = 0; i < count; i++) { struct drm_fb_helper_connector *fb_conn; struct drm_connector *connector; struct drm_encoder *encoder; @@ -388,7 +389,7 @@ retry: fb_conn = fb_helper->connector_info[i]; connector = fb_conn->connector; - if (conn_configured & (1 << i)) + if (conn_configured & BIT(i)) continue; if (pass == 0 && !connector->has_tile) @@ -400,7 +401,7 @@ retry: if (!enabled[i]) { DRM_DEBUG_KMS("connector %s not enabled, skipping\n", connector->name); - conn_configured |= (1 << i); + conn_configured |= BIT(i); continue; } @@ -419,7 +420,7 @@ retry: DRM_DEBUG_KMS("connector %s has no encoder or crtc, skipping\n", connector->name); enabled[i] = false; - conn_configured |= (1 << i); + conn_configured |= BIT(i); continue; } @@ -432,14 +433,15 @@ retry: intel_crtc->lut_b[j] = j; } - new_crtc = intel_fb_helper_crtc(fb_helper, connector->state->crtc); + new_crtc = intel_fb_helper_crtc(fb_helper, + connector->state->crtc); /* * Make sure we're not trying to drive multiple connectors * with a single CRTC, since our cloning support may not * match the BIOS. */ - for (j = 0; j < fb_helper->connector_count; j++) { + for (j = 0; j < count; j++) { if (crtcs[j] == new_crtc) { DRM_DEBUG_KMS("fallback: cloned configuration\n"); goto bail; @@ -498,7 +500,7 @@ retry: modes[i]->flags & DRM_MODE_FLAG_INTERLACE ? "i" :""); fallback = false; - conn_configured |= (1 << i); + conn_configured |= BIT(i); } if ((conn_configured & mask) != mask) { @@ -522,7 +524,7 @@ retry: if (fallback) { bail: DRM_DEBUG_KMS("Not using firmware configuration\n"); - memcpy(enabled, save_enabled, fb_helper->connector_count); + memcpy(enabled, save_enabled, count); kfree(save_enabled); return false; } -- cgit v1.2.3 From ebe69dd366dcb6514be78cfdb8e89d9cc2ebb361 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:36:03 +0100 Subject: drm/i915: Fix inconsistent indenting in vbt_panel_init() smatch complains: drivers/gpu/drm/i915/intel_dsi_panel_vbt.c:657 vbt_panel_init() warn: inconsistent indenting Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-6-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index f122484bedfc..4a3da875b620 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -649,14 +649,13 @@ struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) ); /* - * Exit zero is unified val ths_zero and ths_exit + * Exit zero is unified val ths_zero and ths_exit * minimum value for ths_exit = 110ns * min (exit_zero_cnt * 2) = 110/UI * exit_zero_cnt = 55/UI */ - if (exit_zero_cnt < (55 * ui_den / ui_num)) - if ((55 * ui_den) % ui_num) - exit_zero_cnt += 1; + if (exit_zero_cnt < (55 * ui_den / ui_num) && (55 * ui_den) % ui_num) + exit_zero_cnt += 1; /* clk zero count */ clk_zero_cnt = DIV_ROUND_UP( -- cgit v1.2.3 From 1bbea16a736a1cbf9c1917b472c2b427d4c2a185 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:36:04 +0100 Subject: drm/i915: Fix buffer overflow in dsi_calc_mnp() smatch complain: drivers/gpu/drm/i915/intel_dsi_pll.c:101 dsi_calc_mnp() error: buffer overflow 'lfsr_converts' 39 <= 4294967234 and looks justified in doing so. Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-7-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/intel_dsi_pll.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 4f9930bc89e5..1fcddeb3303d 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -55,12 +55,10 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv, struct intel_crtc_state *config, int target_dsi_clk) { - unsigned int calc_m = 0, calc_p = 0; unsigned int m_min, m_max, p_min = 2, p_max = 6; unsigned int m, n, p; - int ref_clk; - int delta = target_dsi_clk; - u32 m_seed; + unsigned int calc_m, calc_p; + int delta, ref_clk; /* target_dsi_clk is expected in kHz */ if (target_dsi_clk < 300000 || target_dsi_clk > 1150000) { @@ -80,6 +78,10 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv, m_max = 92; } + calc_p = p_min; + calc_m = m_min; + delta = abs(target_dsi_clk - (m_min * ref_clk) / (p_min * n)); + for (m = m_min; m <= m_max && delta; m++) { for (p = p_min; p <= p_max && delta; p++) { /* @@ -97,11 +99,10 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv, } /* register has log2(N1), this works fine for powers of two */ - n = ffs(n) - 1; - m_seed = lfsr_converts[calc_m - 62]; config->dsi_pll.ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2); - config->dsi_pll.div = n << DSI_PLL_N1_DIV_SHIFT | - m_seed << DSI_PLL_M1_DIV_SHIFT; + config->dsi_pll.div = + (ffs(n) - 1) << DSI_PLL_N1_DIV_SHIFT | + (u32)lfsr_converts[calc_m - 62] << DSI_PLL_M1_DIV_SHIFT; return 0; } -- cgit v1.2.3 From f1fda7451f2924d2047bcc696250cb61799a52d9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:36:05 +0100 Subject: drm/i915: Fix inconsistent indentation in intel_pre_enable_lvds() smatch complains: drivers/gpu/drm/i915/intel_lvds.c:187 intel_pre_enable_lvds() warn: inconsistent indenting Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-8-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/intel_lvds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index c26ffef80692..681c6fd72ff6 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -184,8 +184,8 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder) * panels behave in the two modes. For now, let's just maintain the * value we got from the BIOS. */ - temp &= ~LVDS_A3_POWER_MASK; - temp |= lvds_encoder->a3_power; + temp &= ~LVDS_A3_POWER_MASK; + temp |= lvds_encoder->a3_power; /* Set the dithering flag on LVDS as needed, note that there is no * special lvds dither control bit on pch-split platforms, dithering is -- cgit v1.2.3 From 841149909abb4cf9038ba0a12f3bec711f3ce09b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 2 Jul 2016 15:36:06 +0100 Subject: drm/i915: Remove check for !crtc_state in intel_plane_atomic_calc_changes() smatch spotted that: drivers/gpu/drm/i915/intel_display.c:11986 intel_plane_atomic_calc_changes() warn: variable dereferenced before check 'crtc_state' (see line 11972) Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-9-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/intel_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 88e899b46853..32db694a4dc5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11983,8 +11983,7 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state, struct drm_framebuffer *fb = plane_state->fb; int ret; - if (crtc_state && INTEL_INFO(dev)->gen >= 9 && - plane->type != DRM_PLANE_TYPE_CURSOR) { + if (INTEL_GEN(dev) >= 9 && plane->type != DRM_PLANE_TYPE_CURSOR) { ret = skl_update_scaler_plane( to_intel_crtc_state(crtc_state), to_intel_plane_state(plane_state)); -- cgit v1.2.3 From 67d97da34917fb0b21af4c0942a6e03b4b10c094 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:31 +0100 Subject: drm/i915: Only start retire worker when idle The retire worker is a low frequency task that makes sure we retire outstanding requests if userspace is being lax. We only need to start it once as it remains active until the GPU is idle, so do a cheap test before the more expensive queue_work(). A consequence of this is that we need correct locking in the worker to make the hot path of request submission cheap. To keep the symmetry and keep hangcheck strictly bound by the GPU's wakelock, we move the cancel_sync(hangcheck) to the idle worker before dropping the wakelock. v2: Guard against RCU fouling the breadcrumbs bottom-half whilst we kick the waiter. v3: Remove the wakeref assertion squelching (now we hold a wakeref for the hangcheck, any rpm error there is genuine). v4: To prevent excess work when retiring requests, we split the busy flag into two, a boolean to denote whether we hold the wakeref and a bitmask of active engines. v5: Reorder cancelling hangcheck upon idling to avoid a race where we might cancel a hangcheck after being preempted by a new task Signed-off-by: Chris Wilson References: https://bugs.freedesktop.org/show_bug.cgi?id=88437 Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 5 +- drivers/gpu/drm/i915/i915_drv.c | 2 - drivers/gpu/drm/i915/i915_drv.h | 56 ++++++------ drivers/gpu/drm/i915/i915_gem.c | 135 +++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 6 ++ drivers/gpu/drm/i915/i915_irq.c | 15 +--- drivers/gpu/drm/i915/intel_display.c | 25 ------ drivers/gpu/drm/i915/intel_pm.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +- 9 files changed, 135 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index abc4ae8ad498..17b343923b42 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2442,7 +2442,8 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) struct drm_file *file; seq_printf(m, "RPS enabled? %d\n", dev_priv->rps.enabled); - seq_printf(m, "GPU busy? %d\n", dev_priv->mm.busy); + seq_printf(m, "GPU busy? %s [%x]\n", + yesno(dev_priv->gt.awake), dev_priv->gt.active_engines); seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv)); seq_printf(m, "Frequency requested %d; min hard:%d, soft:%d; max soft:%d, hard:%d\n", intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq), @@ -2786,7 +2787,7 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused) if (!HAS_RUNTIME_PM(dev_priv)) seq_puts(m, "Runtime power management not supported\n"); - seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->mm.busy)); + seq_printf(m, "GPU idle: %s\n", yesno(!dev_priv->gt.awake)); seq_printf(m, "IRQs disabled: %s\n", yesno(!intel_irqs_enabled(dev_priv))); #ifdef CONFIG_PM diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 6fa9c0338b1b..2b6494b19869 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2735,8 +2735,6 @@ static int intel_runtime_suspend(struct device *device) i915_gem_release_all_mmaps(dev_priv); mutex_unlock(&dev->struct_mutex); - cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); - intel_guc_suspend(dev); intel_suspend_gt_powersave(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0dcc43d2994b..79ac130606ec 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1313,38 +1313,12 @@ struct i915_gem_mm { /** LRU list of objects with fence regs on them. */ struct list_head fence_list; - /** - * We leave the user IRQ off as much as possible, - * but this means that requests will finish and never - * be retired once the system goes idle. Set a timer to - * fire periodically while the ring is running. When it - * fires, go retire requests. - */ - struct delayed_work retire_work; - - /** - * When we detect an idle GPU, we want to turn on - * powersaving features. So once we see that there - * are no more requests outstanding and no more - * arrive within a small period of time, we fire - * off the idle_work. - */ - struct delayed_work idle_work; - /** * Are we in a non-interruptible section of code like * modesetting? */ bool interruptible; - /** - * Is the GPU currently considered idle, or busy executing userspace - * requests? Whilst idle, we attempt to power down the hardware and - * display clocks. In order to reduce the effect on performance, there - * is a slight delay before we do so. - */ - bool busy; - /* the indicator for dispatch video commands on two BSD rings */ unsigned int bsd_ring_dispatch_index; @@ -2045,6 +2019,34 @@ struct drm_i915_private { int (*init_engines)(struct drm_device *dev); void (*cleanup_engine)(struct intel_engine_cs *engine); void (*stop_engine)(struct intel_engine_cs *engine); + + /** + * Is the GPU currently considered idle, or busy executing + * userspace requests? Whilst idle, we allow runtime power + * management to power down the hardware and display clocks. + * In order to reduce the effect on performance, there + * is a slight delay before we do so. + */ + unsigned int active_engines; + bool awake; + + /** + * We leave the user IRQ off as much as possible, + * but this means that requests will finish and never + * be retired once the system goes idle. Set a timer to + * fire periodically while the ring is running. When it + * fires, go retire requests. + */ + struct delayed_work retire_work; + + /** + * When we detect an idle GPU, we want to turn on + * powersaving features. So once we see that there + * are no more requests outstanding and no more + * arrive within a small period of time, we fire + * off the idle_work. + */ + struct delayed_work idle_work; } gt; /* perform PHY state sanity checks? */ @@ -3315,7 +3317,7 @@ int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno); struct drm_i915_gem_request * i915_gem_find_active_request(struct intel_engine_cs *engine); -bool i915_gem_retire_requests(struct drm_i915_private *dev_priv); +void i915_gem_retire_requests(struct drm_i915_private *dev_priv); void i915_gem_retire_requests_ring(struct intel_engine_cs *engine); static inline u32 i915_reset_counter(struct i915_gpu_error *error) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f21657f8c102..133060c0f96f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2809,6 +2809,26 @@ i915_gem_get_seqno(struct drm_i915_private *dev_priv, u32 *seqno) return 0; } +static void i915_gem_mark_busy(const struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + + dev_priv->gt.active_engines |= intel_engine_flag(engine); + if (dev_priv->gt.awake) + return; + + intel_runtime_pm_get_noresume(dev_priv); + dev_priv->gt.awake = true; + + i915_update_gfx_val(dev_priv); + if (INTEL_GEN(dev_priv) >= 6) + gen6_rps_busy(dev_priv); + + queue_delayed_work(dev_priv->wq, + &dev_priv->gt.retire_work, + round_jiffies_up_relative(HZ)); +} + /* * NB: This function is not allowed to fail. Doing so would mean the the * request is not being tracked for completion but the work itself is @@ -2819,7 +2839,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, bool flush_caches) { struct intel_engine_cs *engine; - struct drm_i915_private *dev_priv; struct intel_ringbuffer *ringbuf; u32 request_start; u32 reserved_tail; @@ -2829,7 +2848,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, return; engine = request->engine; - dev_priv = request->i915; ringbuf = request->ringbuf; /* @@ -2895,12 +2913,6 @@ void __i915_add_request(struct drm_i915_gem_request *request, } /* Not allowed to fail! */ WARN(ret, "emit|add_request failed: %d!\n", ret); - - queue_delayed_work(dev_priv->wq, - &dev_priv->mm.retire_work, - round_jiffies_up_relative(HZ)); - intel_mark_busy(dev_priv); - /* Sanity check that the reserved size was large enough. */ ret = intel_ring_get_tail(ringbuf) - request_start; if (ret < 0) @@ -2909,6 +2921,8 @@ void __i915_add_request(struct drm_i915_gem_request *request, "Not enough space reserved (%d bytes) " "for adding the request (%d bytes)\n", reserved_tail, ret); + + i915_gem_mark_busy(engine); } static bool i915_context_is_banned(struct drm_i915_private *dev_priv, @@ -3223,46 +3237,49 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *engine) WARN_ON(i915_verify_lists(engine->dev)); } -bool -i915_gem_retire_requests(struct drm_i915_private *dev_priv) +void i915_gem_retire_requests(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; - bool idle = true; + + lockdep_assert_held(&dev_priv->dev->struct_mutex); + + if (dev_priv->gt.active_engines == 0) + return; + + GEM_BUG_ON(!dev_priv->gt.awake); for_each_engine(engine, dev_priv) { i915_gem_retire_requests_ring(engine); - idle &= list_empty(&engine->request_list); - if (i915.enable_execlists) { - spin_lock_bh(&engine->execlist_lock); - idle &= list_empty(&engine->execlist_queue); - spin_unlock_bh(&engine->execlist_lock); - } + if (list_empty(&engine->request_list)) + dev_priv->gt.active_engines &= ~intel_engine_flag(engine); } - if (idle) + if (dev_priv->gt.active_engines == 0) mod_delayed_work(dev_priv->wq, - &dev_priv->mm.idle_work, + &dev_priv->gt.idle_work, msecs_to_jiffies(100)); - - return idle; } static void i915_gem_retire_work_handler(struct work_struct *work) { struct drm_i915_private *dev_priv = - container_of(work, typeof(*dev_priv), mm.retire_work.work); + container_of(work, typeof(*dev_priv), gt.retire_work.work); struct drm_device *dev = dev_priv->dev; - bool idle; /* Come back later if the device is busy... */ - idle = false; if (mutex_trylock(&dev->struct_mutex)) { - idle = i915_gem_retire_requests(dev_priv); + i915_gem_retire_requests(dev_priv); mutex_unlock(&dev->struct_mutex); } - if (!idle) - queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, + + /* Keep the retire handler running until we are finally idle. + * We do not need to do this test under locking as in the worst-case + * we queue the retire worker once too often. + */ + if (lockless_dereference(dev_priv->gt.awake)) + queue_delayed_work(dev_priv->wq, + &dev_priv->gt.retire_work, round_jiffies_up_relative(HZ)); } @@ -3270,25 +3287,55 @@ static void i915_gem_idle_work_handler(struct work_struct *work) { struct drm_i915_private *dev_priv = - container_of(work, typeof(*dev_priv), mm.idle_work.work); + container_of(work, typeof(*dev_priv), gt.idle_work.work); struct drm_device *dev = dev_priv->dev; struct intel_engine_cs *engine; + unsigned int stuck_engines; + bool rearm_hangcheck; + + if (!READ_ONCE(dev_priv->gt.awake)) + return; + + if (READ_ONCE(dev_priv->gt.active_engines)) + return; + + rearm_hangcheck = + cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); + + if (!mutex_trylock(&dev->struct_mutex)) { + /* Currently busy, come back later */ + mod_delayed_work(dev_priv->wq, + &dev_priv->gt.idle_work, + msecs_to_jiffies(50)); + goto out_rearm; + } + + if (dev_priv->gt.active_engines) + goto out_unlock; for_each_engine(engine, dev_priv) - if (!list_empty(&engine->request_list)) - return; + i915_gem_batch_pool_fini(&engine->batch_pool); - /* we probably should sync with hangcheck here, using cancel_work_sync. - * Also locking seems to be fubar here, engine->request_list is protected - * by dev->struct_mutex. */ + GEM_BUG_ON(!dev_priv->gt.awake); + dev_priv->gt.awake = false; + rearm_hangcheck = false; - intel_mark_idle(dev_priv); + stuck_engines = intel_kick_waiters(dev_priv); + if (unlikely(stuck_engines)) { + DRM_DEBUG_DRIVER("kicked stuck waiters...missed irq\n"); + dev_priv->gpu_error.missed_irq_rings |= stuck_engines; + } - if (mutex_trylock(&dev->struct_mutex)) { - for_each_engine(engine, dev_priv) - i915_gem_batch_pool_fini(&engine->batch_pool); + if (INTEL_GEN(dev_priv) >= 6) + gen6_rps_idle(dev_priv); + intel_runtime_pm_put(dev_priv); +out_unlock: + mutex_unlock(&dev->struct_mutex); - mutex_unlock(&dev->struct_mutex); +out_rearm: + if (rearm_hangcheck) { + GEM_BUG_ON(!dev_priv->gt.awake); + i915_queue_hangcheck(dev_priv); } } @@ -4421,7 +4468,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) ret = __i915_wait_request(target, true, NULL, NULL); if (ret == 0) - queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, 0); + queue_delayed_work(dev_priv->wq, &dev_priv->gt.retire_work, 0); i915_gem_request_unreference(target); @@ -4939,13 +4986,13 @@ i915_gem_suspend(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); - cancel_delayed_work_sync(&dev_priv->mm.retire_work); - flush_delayed_work(&dev_priv->mm.idle_work); + cancel_delayed_work_sync(&dev_priv->gt.retire_work); + flush_delayed_work(&dev_priv->gt.idle_work); /* Assert that we sucessfully flushed all the work and * reset the GPU back to its idle, low power state. */ - WARN_ON(dev_priv->mm.busy); + WARN_ON(dev_priv->gt.awake); return 0; @@ -5247,9 +5294,9 @@ i915_gem_load_init(struct drm_device *dev) init_engine_lists(&dev_priv->engine[i]); for (i = 0; i < I915_MAX_NUM_FENCES; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); - INIT_DELAYED_WORK(&dev_priv->mm.retire_work, + INIT_DELAYED_WORK(&dev_priv->gt.retire_work, i915_gem_retire_work_handler); - INIT_DELAYED_WORK(&dev_priv->mm.idle_work, + INIT_DELAYED_WORK(&dev_priv->gt.idle_work, i915_gem_idle_work_handler); init_waitqueue_head(&dev_priv->gpu_error.wait_queue); init_waitqueue_head(&dev_priv->gpu_error.reset_queue); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 7941f1fe9cd2..39c53d97833a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1477,6 +1477,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, dispatch_flags |= I915_DISPATCH_RS; } + /* Take a local wakeref for preparing to dispatch the execbuf as + * we expect to access the hardware fairly frequently in the + * process. Upon first dispatch, we acquire another prolonged + * wakeref that we hold until the GPU has been idle for at least + * 100ms. + */ intel_runtime_pm_get(dev_priv); ret = i915_mutex_lock_interruptible(dev); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 53d4c8088f28..80d162acda1b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3103,12 +3103,8 @@ static void i915_hangcheck_elapsed(struct work_struct *work) if (!i915.enable_hangcheck) return; - /* - * The hangcheck work is synced during runtime suspend, we don't - * require a wakeref. TODO: instead of disabling the asserts make - * sure that we hold a reference when this work is running. - */ - DISABLE_RPM_WAKEREF_ASSERTS(dev_priv); + if (!lockless_dereference(dev_priv->gt.awake)) + return; /* As enabling the GPU requires fairly extensive mmio access, * periodically arm the mmio checker to see if we are triggering @@ -3216,17 +3212,12 @@ static void i915_hangcheck_elapsed(struct work_struct *work) } } - if (rings_hung) { + if (rings_hung) i915_handle_error(dev_priv, rings_hung, "Engine(s) hung"); - goto out; - } /* Reset timer in case GPU hangs without another request being added */ if (busy_count) i915_queue_hangcheck(dev_priv); - -out: - ENABLE_RPM_WAKEREF_ASSERTS(dev_priv); } static void ibx_irq_reset(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 32db694a4dc5..acb89e7edd61 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11005,31 +11005,6 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, return mode; } -void intel_mark_busy(struct drm_i915_private *dev_priv) -{ - if (dev_priv->mm.busy) - return; - - intel_runtime_pm_get(dev_priv); - i915_update_gfx_val(dev_priv); - if (INTEL_GEN(dev_priv) >= 6) - gen6_rps_busy(dev_priv); - dev_priv->mm.busy = true; -} - -void intel_mark_idle(struct drm_i915_private *dev_priv) -{ - if (!dev_priv->mm.busy) - return; - - dev_priv->mm.busy = false; - - if (INTEL_GEN(dev_priv) >= 6) - gen6_rps_idle(dev_priv); - - intel_runtime_pm_put(dev_priv); -} - static void intel_crtc_destroy(struct drm_crtc *crtc) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1ded2ca0f2d5..48e21c729eb0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4899,7 +4899,7 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv, /* This is intentionally racy! We peek at the state here, then * validate inside the RPS worker. */ - if (!(dev_priv->mm.busy && + if (!(dev_priv->gt.awake && dev_priv->rps.enabled && dev_priv->rps.cur_freq < dev_priv->rps.max_freq_softlimit)) return; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 41cc9f395a9c..321e1c61ce9f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -360,13 +360,13 @@ struct intel_engine_cs { }; static inline bool -intel_engine_initialized(struct intel_engine_cs *engine) +intel_engine_initialized(const struct intel_engine_cs *engine) { return engine->i915 != NULL; } static inline unsigned -intel_engine_flag(struct intel_engine_cs *engine) +intel_engine_flag(const struct intel_engine_cs *engine) { return 1 << engine->id; } -- cgit v1.2.3 From 1b51bce27b58881275e855a9630918297ce867b8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:32 +0100 Subject: drm/i915: Do not keep postponing the idle-work Rather than persistently postponing the idle-work everytime somebody calls i915_gem_retire_requests() (potentially ensuring that we never reach the idle state), queue the work the first time we detect all requests are complete. Then if in 100ms, more requests have been queued, we will abort the idle-worker and wait again until all the new requests have been completed. Of course, this does depend upon the idle worker cancelling itself gracefully from the previous patch. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 133060c0f96f..78057fafd4bc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3255,9 +3255,9 @@ void i915_gem_retire_requests(struct drm_i915_private *dev_priv) } if (dev_priv->gt.active_engines == 0) - mod_delayed_work(dev_priv->wq, - &dev_priv->gt.idle_work, - msecs_to_jiffies(100)); + queue_delayed_work(dev_priv->wq, + &dev_priv->gt.idle_work, + msecs_to_jiffies(100)); } static void -- cgit v1.2.3 From e307d62d5faba86622c19dca43883ac37bd8e34a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:33 +0100 Subject: drm/i915: Remove redundant queue_delayed_work() from throttle ioctl We know, by design, that whilst the GPU is active (and thus we are throttling) the retire_worker is queued. Therefore attempting to requeue it with queue_delayed_work() is a no-op and we can safely remove it. Signed-off-by: Chris Wilson Reviewed-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-3-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 78057fafd4bc..e6675b981e0e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4467,9 +4467,6 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) return 0; ret = __i915_wait_request(target, true, NULL, NULL); - if (ret == 0) - queue_delayed_work(dev_priv->wq, &dev_priv->gt.retire_work, 0); - i915_gem_request_unreference(target); return ret; -- cgit v1.2.3 From 0e6883b043754a44a682a8f8393862e0ef0490dc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:34 +0100 Subject: drm/i915: Restore waitboost credit to the synchronous waiter Ideally, we want to automagically have the GPU respond to the instantaneous load by reclocking itself. However, reclocking occurs relatively slowly, and to the client waiting for a result from the GPU, too late. To compensate and reduce the client latency, we allow the first wait from a client to boost the GPU clocks to maximum. This overcomes the lag in autoreclocking, at the expense of forcing the GPU clocks too high. So to offset the excessive power usage, we currently allow a client to only boost the clocks once before we detect the GPU is idle again. This works reasonably for say the first frame in a benchmark, but for many more synchronous workloads (like OpenCL) we find the GPU clocks remain too low. By noting a wait which would idle the GPU (i.e. we just waited upon the last known request), we can give that client the idle boost credit (for their next wait) without the 100ms delay required for us to detect the GPU idle state. The intention is to boost clients that are stalling in the process of feeding the GPU more work (and who in doing so let the GPU idle), without granting boost credits to clients that are throttling themselves (such as compositors). Signed-off-by: Chris Wilson Cc: "Zou, Nanhai" Cc: Jesse Barnes Reviewed-by: Jesse Barnes Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-4-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e6675b981e0e..037b26e2a960 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1542,6 +1542,22 @@ complete: *timeout = 0; } + if (rps && req->seqno == req->engine->last_submitted_seqno) { + /* The GPU is now idle and this client has stalled. + * Since no other client has submitted a request in the + * meantime, assume that this client is the only one + * supplying work to the GPU but is unable to keep that + * work supplied because it is waiting. Since the GPU is + * then never kept fully busy, RPS autoclocking will + * keep the clocks relatively low, causing further delays. + * Compensate by giving the synchronous client credit for + * a waitboost next time. + */ + spin_lock(&req->i915->rps.client_lock); + list_del_init(&rps->link); + spin_unlock(&req->i915->rps.client_lock); + } + return ret; } -- cgit v1.2.3 From df4ba5099f80dac5f822c22937c37860ddd8e434 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:35 +0100 Subject: drm/i915: Add background commentary to "waitboosting" Describe the intent of boosting the GPU frequency to maximum before waiting on the GPU. RPS waitboosting was introduced with commit b29c19b64528 ("drm/i915: Boost RPS frequency for CPU stalls") but lacked a concise comment in the code to explain itself. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-5-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 037b26e2a960..b11884d656cf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1462,6 +1462,21 @@ int __i915_wait_request(struct drm_i915_gem_request *req, trace_i915_gem_request_wait_begin(req); + /* This client is about to stall waiting for the GPU. In many cases + * this is undesirable and limits the throughput of the system, as + * many clients cannot continue processing user input/output whilst + * blocked. RPS autotuning may take tens of milliseconds to respond + * to the GPU load and thus incurs additional latency for the client. + * We can circumvent that by promoting the GPU frequency to maximum + * before we wait. This makes the GPU throttle up much more quickly + * (good for benchmarks and user experience, e.g. window animations), + * but at a cost of spending more power processing the workload + * (bad for battery). Not all clients even want their results + * immediately and for them we should just let the GPU select its own + * frequency to maximise efficiency. To prevent a single client from + * forcing the clocks too high for the whole system, we only allow + * each client to waitboost once in a busy period. + */ if (INTEL_INFO(req->i915)->gen >= 6) gen6_rps_boost(req->i915, rps, req->emitted_jiffies); -- cgit v1.2.3 From c33d247d0e31df48ada35d71d1dc7830a4bb4314 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:36 +0100 Subject: drm/i915: Flush the RPS bottom-half when the GPU idles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the RPS bottom-half is flushed before we set the idle frequency when we decide the GPU is idle. This should prevent any races with the bottom-half and setting the idle frequency, and ensures that the bottom-half is bounded by the GPU's rpm reference taken for when it is active (i.e. between gen6_rps_busy() and gen6_rps_idle()). v2: Avoid recursively using the i915->wq - RPS does not touch the struct_mutex so has no place being on the ordered i915->wq. v3: Enable/disable interrupts for RPS busy/idle in order to prevent further HW access from RPS outside of the wakeref. Signed-off-by: Chris Wilson Cc: Imre Deak Cc: Jesse Barnes References: https://bugs.freedesktop.org/show_bug.cgi?id=89728 Reviewed-by: Michał Winiarski Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-6-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 3 --- drivers/gpu/drm/i915/i915_irq.c | 32 ++++++++++++-------------------- drivers/gpu/drm/i915/intel_pm.c | 11 ++++++++++- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2b6494b19869..40521a3e8b8f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2737,7 +2737,6 @@ static int intel_runtime_suspend(struct device *device) intel_guc_suspend(dev); - intel_suspend_gt_powersave(dev_priv); intel_runtime_pm_disable_interrupts(dev_priv); ret = 0; @@ -2852,8 +2851,6 @@ static int intel_runtime_resume(struct device *device) if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) intel_hpd_init(dev_priv); - intel_enable_gt_powersave(dev_priv); - enable_rpm_wakeref_asserts(dev_priv); if (ret) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 80d162acda1b..f0535df41dfd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -351,9 +351,8 @@ void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) { spin_lock_irq(&dev_priv->irq_lock); - - WARN_ON(dev_priv->rps.pm_iir); - WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); + WARN_ON_ONCE(dev_priv->rps.pm_iir); + WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); dev_priv->rps.interrupts_enabled = true; I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) | dev_priv->pm_rps_events); @@ -371,11 +370,6 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) { spin_lock_irq(&dev_priv->irq_lock); dev_priv->rps.interrupts_enabled = false; - spin_unlock_irq(&dev_priv->irq_lock); - - cancel_work_sync(&dev_priv->rps.work); - - spin_lock_irq(&dev_priv->irq_lock); I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0)); @@ -384,8 +378,15 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) ~dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); - synchronize_irq(dev_priv->dev->irq); + + /* Now that we will not be generating any more work, flush any + * outsanding tasks. As we are called on the RPS idle path, + * we will reset the GPU to minimum frequencies, so the current + * state of the worker can be discarded. + */ + cancel_work_sync(&dev_priv->rps.work); + gen6_reset_rps_interrupts(dev_priv); } /** @@ -1082,13 +1083,6 @@ static void gen6_pm_rps_work(struct work_struct *work) return; } - /* - * The RPS work is synced during runtime suspend, we don't require a - * wakeref. TODO: instead of disabling the asserts make sure that we - * always hold an RPM reference while the work is running. - */ - DISABLE_RPM_WAKEREF_ASSERTS(dev_priv); - pm_iir = dev_priv->rps.pm_iir; dev_priv->rps.pm_iir = 0; /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ @@ -1101,7 +1095,7 @@ static void gen6_pm_rps_work(struct work_struct *work) WARN_ON(pm_iir & ~dev_priv->pm_rps_events); if ((pm_iir & dev_priv->pm_rps_events) == 0 && !client_boost) - goto out; + return; mutex_lock(&dev_priv->rps.hw_lock); @@ -1156,8 +1150,6 @@ static void gen6_pm_rps_work(struct work_struct *work) intel_set_rps(dev_priv, new_delay); mutex_unlock(&dev_priv->rps.hw_lock); -out: - ENABLE_RPM_WAKEREF_ASSERTS(dev_priv); } @@ -1597,7 +1589,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) gen6_disable_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); if (dev_priv->rps.interrupts_enabled) { dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; - queue_work(dev_priv->wq, &dev_priv->rps.work); + schedule_work(&dev_priv->rps.work); } spin_unlock(&dev_priv->irq_lock); } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 48e21c729eb0..814b0dfaf640 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4864,6 +4864,8 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); + gen6_enable_rps_interrupts(dev_priv); + /* Ensure we start at the user's desired frequency */ intel_set_rps(dev_priv, clamp(dev_priv->rps.cur_freq, @@ -4875,6 +4877,13 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) void gen6_rps_idle(struct drm_i915_private *dev_priv) { + /* Flush our bottom-half so that it does not race with us + * setting the idle frequency and so that it is bounded by + * our rpm wakeref. And then disable the interrupts to stop any + * futher RPS reclocking whilst we are asleep. + */ + gen6_disable_rps_interrupts(dev_priv); + mutex_lock(&dev_priv->rps.hw_lock); if (dev_priv->rps.enabled) { if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) @@ -4915,7 +4924,7 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv, spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->rps.interrupts_enabled) { dev_priv->rps.client_boost = true; - queue_work(dev_priv->wq, &dev_priv->rps.work); + schedule_work(&dev_priv->rps.work); } spin_unlock_irq(&dev_priv->irq_lock); -- cgit v1.2.3 From 7b4d3a16dd97be0ebc793ea046b9af9d5c9b1b1a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:37 +0100 Subject: drm/i915: Remove stop-rings debugfs interface Now that we have (near) universal GPU recovery code, we can inject a real hang from userspace and not need any fakery. Not only does this mean that the testing is far more realistic, but we can simplify the kernel in the process. Signed-off-by: Chris Wilson Reviewed-by: Arun Siluvery Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-7-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 35 -------------------------- drivers/gpu/drm/i915/i915_drv.c | 17 ++----------- drivers/gpu/drm/i915/i915_drv.h | 19 -------------- drivers/gpu/drm/i915/i915_gem.c | 44 ++++++++++----------------------- drivers/gpu/drm/i915/intel_lrc.c | 3 --- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ------ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 - 7 files changed, 15 insertions(+), 112 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 17b343923b42..e4409ddc60e5 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4830,40 +4830,6 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_wedged_fops, i915_wedged_get, i915_wedged_set, "%llu\n"); -static int -i915_ring_stop_get(void *data, u64 *val) -{ - struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; - - *val = dev_priv->gpu_error.stop_rings; - - return 0; -} - -static int -i915_ring_stop_set(void *data, u64 val) -{ - struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - - DRM_DEBUG_DRIVER("Stopping rings 0x%08llx\n", val); - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - dev_priv->gpu_error.stop_rings = val; - mutex_unlock(&dev->struct_mutex); - - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(i915_ring_stop_fops, - i915_ring_stop_get, i915_ring_stop_set, - "0x%08llx\n"); - static int i915_ring_missed_irq_get(void *data, u64 *val) { @@ -5493,7 +5459,6 @@ static const struct i915_debugfs_files { {"i915_max_freq", &i915_max_freq_fops}, {"i915_min_freq", &i915_min_freq_fops}, {"i915_cache_sharing", &i915_cache_sharing_fops}, - {"i915_ring_stop", &i915_ring_stop_fops}, {"i915_ring_missed_irq", &i915_ring_missed_irq_fops}, {"i915_ring_test_irq", &i915_ring_test_irq_fops}, {"i915_gem_drop_caches", &i915_drop_caches_fops}, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 40521a3e8b8f..7b9b6f90ca69 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2159,24 +2159,11 @@ int i915_reset(struct drm_i915_private *dev_priv) goto error; } + pr_notice("drm/i915: Resetting chip after gpu hang\n"); + i915_gem_reset(dev); ret = intel_gpu_reset(dev_priv, ALL_ENGINES); - - /* Also reset the gpu hangman. */ - if (error->stop_rings != 0) { - DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); - error->stop_rings = 0; - if (ret == -ENODEV) { - DRM_INFO("Reset not implemented, but ignoring " - "error for simulated gpu hangs\n"); - ret = 0; - } - } - - if (i915_stop_ring_allow_warn(dev_priv)) - pr_notice("drm/i915: Resetting chip after gpu hang\n"); - if (ret) { if (ret != -ENODEV) DRM_ERROR("Failed to reset chip: %i\n", ret); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 79ac130606ec..488891853cb5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1402,13 +1402,6 @@ struct i915_gpu_error { */ wait_queue_head_t reset_queue; - /* Userspace knobs for gpu hang simulation; - * combines both a ring mask, and extra flags - */ - u32 stop_rings; -#define I915_STOP_RING_ALLOW_BAN (1 << 31) -#define I915_STOP_RING_ALLOW_WARN (1 << 30) - /* For missed irq/seqno simulation. */ unsigned long test_irq_rings; }; @@ -3360,18 +3353,6 @@ static inline u32 i915_reset_count(struct i915_gpu_error *error) return ((i915_reset_counter(error) & ~I915_WEDGED) + 1) / 2; } -static inline bool i915_stop_ring_allow_ban(struct drm_i915_private *dev_priv) -{ - return dev_priv->gpu_error.stop_rings == 0 || - dev_priv->gpu_error.stop_rings & I915_STOP_RING_ALLOW_BAN; -} - -static inline bool i915_stop_ring_allow_warn(struct drm_i915_private *dev_priv) -{ - return dev_priv->gpu_error.stop_rings == 0 || - dev_priv->gpu_error.stop_rings & I915_STOP_RING_ALLOW_WARN; -} - void i915_gem_reset(struct drm_device *dev); bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); int __must_check i915_gem_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b11884d656cf..94d68f9c3a08 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2956,44 +2956,30 @@ void __i915_add_request(struct drm_i915_gem_request *request, i915_gem_mark_busy(engine); } -static bool i915_context_is_banned(struct drm_i915_private *dev_priv, - const struct i915_gem_context *ctx) +static bool i915_context_is_banned(const struct i915_gem_context *ctx) { unsigned long elapsed; - elapsed = get_seconds() - ctx->hang_stats.guilty_ts; - if (ctx->hang_stats.banned) return true; + elapsed = get_seconds() - ctx->hang_stats.guilty_ts; if (ctx->hang_stats.ban_period_seconds && elapsed <= ctx->hang_stats.ban_period_seconds) { - if (!i915_gem_context_is_default(ctx)) { - DRM_DEBUG("context hanging too fast, banning!\n"); - return true; - } else if (i915_stop_ring_allow_ban(dev_priv)) { - if (i915_stop_ring_allow_warn(dev_priv)) - DRM_ERROR("gpu hanging too fast, banning!\n"); - return true; - } + DRM_DEBUG("context hanging too fast, banning!\n"); + return true; } return false; } -static void i915_set_reset_status(struct drm_i915_private *dev_priv, - struct i915_gem_context *ctx, +static void i915_set_reset_status(struct i915_gem_context *ctx, const bool guilty) { - struct i915_ctx_hang_stats *hs; - - if (WARN_ON(!ctx)) - return; - - hs = &ctx->hang_stats; + struct i915_ctx_hang_stats *hs = &ctx->hang_stats; if (guilty) { - hs->banned = i915_context_is_banned(dev_priv, ctx); + hs->banned = i915_context_is_banned(ctx); hs->batch_active++; hs->guilty_ts = get_seconds(); } else { @@ -3119,27 +3105,23 @@ i915_gem_find_active_request(struct intel_engine_cs *engine) return NULL; } -static void i915_gem_reset_engine_status(struct drm_i915_private *dev_priv, - struct intel_engine_cs *engine) +static void i915_gem_reset_engine_status(struct intel_engine_cs *engine) { struct drm_i915_gem_request *request; bool ring_hung; request = i915_gem_find_active_request(engine); - if (request == NULL) return; ring_hung = engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG; - i915_set_reset_status(dev_priv, request->ctx, ring_hung); - + i915_set_reset_status(request->ctx, ring_hung); list_for_each_entry_continue(request, &engine->request_list, list) - i915_set_reset_status(dev_priv, request->ctx, false); + i915_set_reset_status(request->ctx, false); } -static void i915_gem_reset_engine_cleanup(struct drm_i915_private *dev_priv, - struct intel_engine_cs *engine) +static void i915_gem_reset_engine_cleanup(struct intel_engine_cs *engine) { struct intel_ringbuffer *buffer; @@ -3209,10 +3191,10 @@ void i915_gem_reset(struct drm_device *dev) * their reference to the objects, the inspection must be done first. */ for_each_engine(engine, dev_priv) - i915_gem_reset_engine_status(dev_priv, engine); + i915_gem_reset_engine_status(engine); for_each_engine(engine, dev_priv) - i915_gem_reset_engine_cleanup(dev_priv, engine); + i915_gem_reset_engine_cleanup(engine); i915_gem_context_reset(dev); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 380175149916..2e66f310595f 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -789,9 +789,6 @@ intel_logical_ring_advance_and_submit(struct drm_i915_gem_request *request) intel_logical_ring_emit(ringbuf, MI_NOOP); intel_logical_ring_advance(ringbuf); - if (intel_engine_stopped(engine)) - return 0; - /* We keep the previous context alive until we retire the following * request. This ensures that any the context object is still pinned * for any residual writes the HW makes into it on the context switch diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a924a9f9eb4d..3fafc35d99c1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -58,18 +58,10 @@ void intel_ring_update_space(struct intel_ringbuffer *ringbuf) ringbuf->tail, ringbuf->size); } -bool intel_engine_stopped(struct intel_engine_cs *engine) -{ - struct drm_i915_private *dev_priv = engine->i915; - return dev_priv->gpu_error.stop_rings & intel_engine_flag(engine); -} - static void __intel_ring_advance(struct intel_engine_cs *engine) { struct intel_ringbuffer *ringbuf = engine->buffer; ringbuf->tail &= ringbuf->size - 1; - if (intel_engine_stopped(engine)) - return; engine->write_tail(engine, ringbuf->tail); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 321e1c61ce9f..121294c602c3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -468,7 +468,6 @@ static inline void intel_ring_advance(struct intel_engine_cs *engine) } int __intel_ring_space(int head, int tail, int size); void intel_ring_update_space(struct intel_ringbuffer *ringbuf); -bool intel_engine_stopped(struct intel_engine_cs *engine); int __must_check intel_engine_idle(struct intel_engine_cs *engine); void intel_ring_init_seqno(struct intel_engine_cs *engine, u32 seqno); -- cgit v1.2.3 From ba6e0418064de8c4dee914a5eb8574affe19e6f5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:38 +0100 Subject: drm/i915: Record the ringbuffer associated with the request The request tells us where to read the ringbuf from, so use that information to simplify the error capture. If no request was active at the time of the hang, the ring is idle and there is no information inside the ring pertaining to the hang. Note carefully that this will reduce the amount of information stored in the error state - any ring without an active request will not be recorded. Signed-off-by: Chris Wilson Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-8-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gpu_error.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 3a46a84fe3e3..1be63590a7fe 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1077,7 +1077,6 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, for (i = 0; i < I915_NUM_ENGINES; i++) { struct intel_engine_cs *engine = &dev_priv->engine[i]; - struct intel_ringbuffer *rbuf; error->ring[i].pid = -1; @@ -1092,6 +1091,7 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, request = i915_gem_find_active_request(engine); if (request) { struct i915_address_space *vm; + struct intel_ringbuffer *rb; vm = request->ctx && request->ctx->ppgtt ? &request->ctx->ppgtt->base : @@ -1122,26 +1122,14 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, } rcu_read_unlock(); } - } - if (i915.enable_execlists) { - /* TODO: This is only a small fix to keep basic error - * capture working, but we need to add more information - * for it to be useful (e.g. dump the context being - * executed). - */ - if (request) - rbuf = request->ctx->engine[engine->id].ringbuf; - else - rbuf = dev_priv->kernel_context->engine[engine->id].ringbuf; - } else - rbuf = engine->buffer; - - error->ring[i].cpu_ring_head = rbuf->head; - error->ring[i].cpu_ring_tail = rbuf->tail; - - error->ring[i].ringbuffer = - i915_error_ggtt_object_create(dev_priv, rbuf->obj); + rb = request->ringbuf; + error->ring[i].cpu_ring_head = rb->head; + error->ring[i].cpu_ring_tail = rb->tail; + error->ring[i].ringbuffer = + i915_error_ggtt_object_create(dev_priv, + rb->obj); + } error->ring[i].hws_page = i915_error_ggtt_object_create(dev_priv, -- cgit v1.2.3 From bc3d674462e5df5f2b33adbfcaad9edff8b827f4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:08:39 +0100 Subject: drm/i915: Allow userspace to request no-error-capture upon GPU hangs igt likes to inject GPU hangs into its command streams. However, as we expect these hangs, we don't actually want them recorded in the dmesg output or stored in the i915_error_state (usually). To accommodate this allow userspace to set a flag on the context that any hang emanating from that context will not be recorded. We still do the error capture (otherwise how do we find the guilty context and know its intent?) as part of the reason for random GPU hang injection is to exercise the race conditions between the error capture and normal execution. v2: Split out the request->ringbuf error capture changes. v3: Move the flag defines next to the intel_context->flags definition Signed-off-by: Chris Wilson Acked-by: Daniel Vetter Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1467616119-4093-9-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 4 +++- drivers/gpu/drm/i915/i915_gem_context.c | 13 +++++++++++++ drivers/gpu/drm/i915/i915_gpu_error.c | 20 ++++++++++++-------- include/uapi/drm/i915_drm.h | 1 + 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 488891853cb5..251a08d8808d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -475,6 +475,7 @@ struct drm_i915_error_state { struct timeval time; char error_msg[128]; + bool simulated; int iommu; u32 reset_count; u32 suspend_count; @@ -875,9 +876,10 @@ struct i915_gem_context { /* Unique identifier for this context, used by the hw for tracking */ unsigned long flags; +#define CONTEXT_NO_ZEROMAP BIT(0) +#define CONTEXT_NO_ERROR_CAPTURE BIT(1) unsigned hw_id; u32 user_handle; -#define CONTEXT_NO_ZEROMAP (1<<0) u32 ggtt_alignment; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 3a6594b70900..8e952b1a31b3 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -1026,6 +1026,9 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, else args->value = to_i915(dev)->ggtt.base.total; break; + case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE: + args->value = !!(ctx->flags & CONTEXT_NO_ERROR_CAPTURE); + break; default: ret = -EINVAL; break; @@ -1071,6 +1074,16 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, ctx->flags |= args->value ? CONTEXT_NO_ZEROMAP : 0; } break; + case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE: + if (args->size) { + ret = -EINVAL; + } else { + if (args->value) + ctx->flags |= CONTEXT_NO_ERROR_CAPTURE; + else + ctx->flags &= ~CONTEXT_NO_ERROR_CAPTURE; + } + break; default: ret = -EINVAL; break; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 1be63590a7fe..c6e05cccbedf 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1093,9 +1093,8 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, struct i915_address_space *vm; struct intel_ringbuffer *rb; - vm = request->ctx && request->ctx->ppgtt ? - &request->ctx->ppgtt->base : - &ggtt->base; + vm = request->ctx->ppgtt ? + &request->ctx->ppgtt->base : &ggtt->base; /* We need to copy these to an anonymous buffer * as the simplest method to avoid being overwritten @@ -1123,6 +1122,9 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, rcu_read_unlock(); } + error->simulated |= + request->ctx->flags & CONTEXT_NO_ERROR_CAPTURE; + rb = request->ringbuf; error->ring[i].cpu_ring_head = rb->head; error->ring[i].cpu_ring_tail = rb->tail; @@ -1422,12 +1424,14 @@ void i915_capture_error_state(struct drm_i915_private *dev_priv, i915_error_capture_msg(dev_priv, error, engine_mask, error_msg); DRM_INFO("%s\n", error->error_msg); - spin_lock_irqsave(&dev_priv->gpu_error.lock, flags); - if (dev_priv->gpu_error.first_error == NULL) { - dev_priv->gpu_error.first_error = error; - error = NULL; + 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; + error = NULL; + } + spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); } - spin_unlock_irqrestore(&dev_priv->gpu_error.lock, flags); if (error) { i915_error_state_free(&error->ref); diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index a642bbc7777d..d7e81a3886fd 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -1173,6 +1173,7 @@ struct drm_i915_gem_context_param { #define I915_CONTEXT_PARAM_BAN_PERIOD 0x1 #define I915_CONTEXT_PARAM_NO_ZEROMAP 0x2 #define I915_CONTEXT_PARAM_GTT_SIZE 0x3 +#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4 __u64 value; }; -- cgit v1.2.3 From 556ab7a6dea55b20269ab5093b90585c924ad340 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 3 Jul 2016 18:29:33 +0100 Subject: drm/i915: Hold irq uncore.lock when initialising fw_domains Acquiring the forcewake domain asserts that it is in an atomic section (as we always expect to be under the uncore.lock). This is true except for initialising the domains on Ivybridge, and so we generate a warning. Wrap the manual usage of fw_domains inside the spin_lock. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1467566973-13596-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_uncore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index b49a95a18da4..19d759ed7a30 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1299,9 +1299,11 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv) fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER, FORCEWAKE_MT, FORCEWAKE_MT_ACK); + spin_lock_irq(&dev_priv->uncore.lock); fw_domains_get_with_thread_status(dev_priv, FORCEWAKE_ALL); ecobus = __raw_i915_read32(dev_priv, ECOBUS); fw_domains_put_with_fifo(dev_priv, FORCEWAKE_ALL); + spin_unlock_irq(&dev_priv->uncore.lock); if (!(ecobus & FORCEWAKE_MT_ENABLE)) { DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n"); -- cgit v1.2.3 From 3a122c27673691f99120dcaf36bccaa471bfb0df Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Jun 2016 14:35:05 +0100 Subject: drm/i915: Limit i915_ring_test_irq debugfs to actual rings For simplicity in testing, only report known rings in the mask. This allows userspace to try and trigger a missed irq on every ring and do a comparison between i915_ring_test_irq and i915_ring_missed_irq to see if any rings failed. v2: Move the debug message to after the rings are selected (so that the message accurately reflects reality) Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1466170505-8048-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_debugfs.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e4409ddc60e5..3464c23f2fc6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4877,17 +4877,10 @@ i915_ring_test_irq_set(void *data, u64 val) { struct drm_device *dev = data; struct drm_i915_private *dev_priv = dev->dev_private; - int ret; + val &= INTEL_INFO(dev_priv)->ring_mask; DRM_DEBUG_DRIVER("Masking interrupts on rings 0x%08llx\n", val); - - /* Lock against concurrent debugfs callers */ - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - dev_priv->gpu_error.test_irq_rings = val; - mutex_unlock(&dev->struct_mutex); return 0; } -- cgit v1.2.3 From 6f8be28012f46352e5e54752a00946901a926c03 Mon Sep 17 00:00:00 2001 From: Peter Antoine Date: Thu, 30 Jun 2016 09:37:51 -0700 Subject: Revert "drm/i915/kbl: drm/i915: Avoid GuC loading for now on Kabylake." This reverts commit 2b81b84471b9 Cc: Christophe Prigent Signed-off-by: Peter Antoine Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 251a08d8808d..f0b1f43d0601 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2858,7 +2858,7 @@ struct drm_i915_cmd_table { * command submission once loaded. But these are logically independent * properties, so we have separate macros to test them. */ -#define HAS_GUC(dev) (IS_GEN9(dev) && !IS_KABYLAKE(dev)) +#define HAS_GUC(dev) (IS_GEN9(dev)) #define HAS_GUC_UCODE(dev) (HAS_GUC(dev)) #define HAS_GUC_SCHED(dev) (HAS_GUC(dev)) -- cgit v1.2.3 From ff64cc16e25dbfdf36c7e1489b0ad2a90e8c48d1 Mon Sep 17 00:00:00 2001 From: Peter Antoine Date: Thu, 30 Jun 2016 09:37:52 -0700 Subject: i915/guc: Add Kabylake GuC Loading This patch added the loading of the GuC for Kabylake. It loads a 9.14 firmware. v2: Fix commit message v3: Fix major/minor var names to match -nightly. (Rodrigo) Cc: Christophe Prigent Signed-off-by: Peter Antoine Signed-off-by: Michel Thierry Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Reviewed-by: Michel Thierry (v3) Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467304672-2106-1-git-send-email-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_guc_loader.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 4f6311a91a7e..d80b617ad9af 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -65,6 +65,9 @@ MODULE_FIRMWARE(I915_SKL_GUC_UCODE); #define I915_BXT_GUC_UCODE "i915/bxt_guc_ver8_7.bin" MODULE_FIRMWARE(I915_BXT_GUC_UCODE); +#define I915_KBL_GUC_UCODE "i915/kbl_guc_ver9_14.bin" +MODULE_FIRMWARE(I915_KBL_GUC_UCODE); + /* User-friendly representation of an enum */ const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status) { @@ -698,6 +701,10 @@ void intel_guc_init(struct drm_device *dev) fw_path = I915_BXT_GUC_UCODE; guc_fw->guc_fw_major_wanted = 8; guc_fw->guc_fw_minor_wanted = 7; + } else if (IS_KABYLAKE(dev)) { + fw_path = I915_KBL_GUC_UCODE; + guc_fw->guc_fw_major_wanted = 9; + guc_fw->guc_fw_minor_wanted = 14; } else { fw_path = ""; /* unknown device */ } -- cgit v1.2.3 From fac5e23e3c385fde41aab4a23bc50c8c15ad4d00 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 11:34:36 +0100 Subject: drm/i915: Mass convert dev->dev_private to to_i915(dev) Since we now subclass struct drm_device, we can save pointer dances by noting the equivalence of struct drm_device and struct drm_i915_private, i.e. by using to_i915(). text data bss dec hex filename 1073824 4562 416 1078802 107612 drivers/gpu/drm/i915/i915.ko 1068976 4562 416 1073954 106322 drivers/gpu/drm/i915/i915.ko Created by the coccinelle script: @@ expression E; identifier p; @@ - struct drm_i915_private *p = E->dev_private; + struct drm_i915_private *p = to_i915(E); Signed-off-by: Chris Wilson Reviewed-by: Dave Gordon Link: http://patchwork.freedesktop.org/patch/msgid/1467628477-25379-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 172 +++++++-------- drivers/gpu/drm/i915/i915_drv.c | 28 +-- drivers/gpu/drm/i915/i915_gem.c | 54 ++--- drivers/gpu/drm/i915/i915_gem_context.c | 10 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 +- drivers/gpu/drm/i915/i915_gem_fence.c | 24 +-- drivers/gpu/drm/i915/i915_gem_gtt.c | 20 +- drivers/gpu/drm/i915/i915_gem_stolen.c | 6 +- drivers/gpu/drm/i915/i915_gem_tiling.c | 4 +- drivers/gpu/drm/i915/i915_gpu_error.c | 6 +- drivers/gpu/drm/i915/i915_guc_submission.c | 4 +- drivers/gpu/drm/i915/i915_irq.c | 92 ++++---- drivers/gpu/drm/i915/i915_suspend.c | 8 +- drivers/gpu/drm/i915/i915_sysfs.c | 22 +- drivers/gpu/drm/i915/intel_audio.c | 18 +- drivers/gpu/drm/i915/intel_color.c | 18 +- drivers/gpu/drm/i915/intel_crt.c | 24 +-- drivers/gpu/drm/i915/intel_ddi.c | 36 ++-- drivers/gpu/drm/i915/intel_display.c | 286 ++++++++++++------------- drivers/gpu/drm/i915/intel_dp.c | 107 +++++---- drivers/gpu/drm/i915/intel_dp_mst.c | 6 +- drivers/gpu/drm/i915/intel_dpio_phy.c | 10 +- drivers/gpu/drm/i915/intel_dpll_mgr.c | 12 +- drivers/gpu/drm/i915/intel_drv.h | 4 +- drivers/gpu/drm/i915/intel_dsi.c | 36 ++-- drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c | 2 +- drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 6 +- drivers/gpu/drm/i915/intel_dsi_pll.c | 12 +- drivers/gpu/drm/i915/intel_dvo.c | 18 +- drivers/gpu/drm/i915/intel_fbc.c | 24 +-- drivers/gpu/drm/i915/intel_fbdev.c | 10 +- drivers/gpu/drm/i915/intel_fifo_underrun.c | 18 +- drivers/gpu/drm/i915/intel_guc_loader.c | 6 +- drivers/gpu/drm/i915/intel_hdmi.c | 48 ++--- drivers/gpu/drm/i915/intel_i2c.c | 6 +- drivers/gpu/drm/i915/intel_lrc.c | 4 +- drivers/gpu/drm/i915/intel_lvds.c | 16 +- drivers/gpu/drm/i915/intel_modes.c | 4 +- drivers/gpu/drm/i915/intel_overlay.c | 4 +- drivers/gpu/drm/i915/intel_panel.c | 6 +- drivers/gpu/drm/i915/intel_pm.c | 110 +++++----- drivers/gpu/drm/i915/intel_psr.c | 36 ++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 10 +- drivers/gpu/drm/i915/intel_sdvo.c | 22 +- drivers/gpu/drm/i915/intel_sprite.c | 18 +- drivers/gpu/drm/i915/intel_tv.c | 12 +- drivers/gpu/drm/i915/intel_uncore.c | 2 +- 47 files changed, 702 insertions(+), 703 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3464c23f2fc6..8cc453731567 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -265,7 +265,7 @@ static int i915_gem_stolen_list_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; u64 total_obj_size, total_gtt_size; LIST_HEAD(stolen); @@ -591,7 +591,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data) struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; uintptr_t list = (uintptr_t) node->info_ent->data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; u64 total_obj_size, total_gtt_size; int count, ret; @@ -625,7 +625,7 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc; int ret; @@ -695,7 +695,7 @@ static int i915_gem_batch_pool_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; struct intel_engine_cs *engine; int total = 0; @@ -740,7 +740,7 @@ static int i915_gem_request_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; struct drm_i915_gem_request *req; int ret, any; @@ -810,7 +810,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; int ret; @@ -833,7 +833,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; int ret, i, pipe; @@ -1024,7 +1024,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i, ret; ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -1052,7 +1052,7 @@ static int i915_hws_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; const u32 *hws; int i; @@ -1163,7 +1163,7 @@ static int i915_next_seqno_get(void *data, u64 *val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -1200,7 +1200,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; intel_runtime_pm_get(dev_priv); @@ -1403,7 +1403,7 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; u64 acthd[I915_NUM_ENGINES]; u32 seqno[I915_NUM_ENGINES]; @@ -1474,7 +1474,7 @@ static int ironlake_drpc_info(struct seq_file *m) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 rgvmodectl, rstdbyctl; u16 crstandvid; int ret; @@ -1542,7 +1542,7 @@ static int i915_forcewake_domains(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_uncore_forcewake_domain *fw_domain; spin_lock_irq(&dev_priv->uncore.lock); @@ -1560,7 +1560,7 @@ static int vlv_drpc_info(struct seq_file *m) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 rpmodectl1, rcctl1, pw_status; intel_runtime_pm_get(dev_priv); @@ -1600,7 +1600,7 @@ static int gen6_drpc_info(struct seq_file *m) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 rpmodectl1, gt_core_status, rcctl1, rc6vids = 0; unsigned forcewake_count; int count = 0, ret; @@ -1712,7 +1712,7 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); seq_printf(m, "FB tracking busy bits: 0x%08x\n", dev_priv->fb_tracking.busy_bits); @@ -1727,7 +1727,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!HAS_FBC(dev)) { seq_puts(m, "FBC unsupported on this chipset\n"); @@ -1757,7 +1757,7 @@ static int i915_fbc_status(struct seq_file *m, void *unused) static int i915_fbc_fc_get(void *data, u64 *val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (INTEL_INFO(dev)->gen < 7 || !HAS_FBC(dev)) return -ENODEV; @@ -1770,7 +1770,7 @@ static int i915_fbc_fc_get(void *data, u64 *val) static int i915_fbc_fc_set(void *data, u64 val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 reg; if (INTEL_INFO(dev)->gen < 7 || !HAS_FBC(dev)) @@ -1797,7 +1797,7 @@ static int i915_ips_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!HAS_IPS(dev)) { seq_puts(m, "not supported\n"); @@ -1827,7 +1827,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); bool sr_enabled = false; intel_runtime_pm_get(dev_priv); @@ -1856,7 +1856,7 @@ static int i915_emon_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long temp, chipset, gfx; int ret; @@ -1884,7 +1884,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; int gpu_freq, ia_freq; unsigned int max_gpu_freq, min_gpu_freq; @@ -1939,7 +1939,7 @@ static int i915_opregion(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_opregion *opregion = &dev_priv->opregion; int ret; @@ -1960,7 +1960,7 @@ static int i915_vbt(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_opregion *opregion = &dev_priv->opregion; if (opregion->vbt) @@ -2031,7 +2031,7 @@ static int i915_context_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; struct i915_gem_context *ctx; int ret; @@ -2128,7 +2128,7 @@ static int i915_dump_lrc(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; struct i915_gem_context *ctx; int ret; @@ -2155,7 +2155,7 @@ static int i915_execlists(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *)m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; u32 status_pointer; u8 read_pointer; @@ -2258,7 +2258,7 @@ static int i915_swizzle_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -2331,7 +2331,7 @@ static int per_file_ctx(int id, void *ptr, void *data) static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; int i; @@ -2352,7 +2352,7 @@ static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev) static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; if (IS_GEN6(dev_priv)) @@ -2386,7 +2386,7 @@ static int i915_ppgtt_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_file *file; int ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -2438,7 +2438,7 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_file *file; seq_printf(m, "RPS enabled? %d\n", dev_priv->rps.enabled); @@ -2484,7 +2484,7 @@ static int i915_llc(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const bool edram = INTEL_GEN(dev_priv) > 8; seq_printf(m, "LLC: %s\n", yesno(HAS_LLC(dev))); @@ -2497,7 +2497,7 @@ static int i915_llc(struct seq_file *m, void *data) static int i915_guc_load_status_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; - struct drm_i915_private *dev_priv = node->minor->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(node->minor->dev); struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; u32 tmp, i; @@ -2570,7 +2570,7 @@ static int i915_guc_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_guc guc; struct i915_guc_client client = {}; struct intel_engine_cs *engine; @@ -2620,7 +2620,7 @@ static int i915_guc_log_dump(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *log_obj = dev_priv->guc.log_obj; u32 *log; int i = 0, pg; @@ -2648,7 +2648,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 psrperf = 0; u32 stat[3]; enum pipe pipe; @@ -2756,7 +2756,7 @@ static int i915_energy_uJ(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u64 power; u32 units; @@ -2782,7 +2782,7 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!HAS_RUNTIME_PM(dev_priv)) seq_puts(m, "Runtime power management not supported\n"); @@ -2807,7 +2807,7 @@ static int i915_power_domain_info(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_power_domains *power_domains = &dev_priv->power_domains; int i; @@ -2842,7 +2842,7 @@ static int i915_dmc_info(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_csr *csr; if (!HAS_CSR(dev)) { @@ -3033,7 +3033,7 @@ static void intel_connector_info(struct seq_file *m, static bool cursor_active(struct drm_device *dev, int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 state; if (IS_845G(dev) || IS_I865G(dev)) @@ -3046,7 +3046,7 @@ static bool cursor_active(struct drm_device *dev, int pipe) static bool cursor_position(struct drm_device *dev, int pipe, int *x, int *y) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 pos; pos = I915_READ(CURPOS(pipe)); @@ -3167,7 +3167,7 @@ static int i915_display_info(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc; struct drm_connector *connector; @@ -3222,7 +3222,7 @@ static int i915_semaphore_status(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; int num_rings = hweight32(INTEL_INFO(dev)->ring_mask); enum intel_engine_id id; @@ -3295,7 +3295,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; drm_modeset_lock_all(dev); @@ -3325,7 +3325,7 @@ static int i915_wa_registers(struct seq_file *m, void *unused) struct intel_engine_cs *engine; struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_workarounds *workarounds = &dev_priv->workarounds; enum intel_engine_id id; @@ -3363,7 +3363,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; struct drm_device *dev = node->minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct skl_ddb_allocation *ddb; struct skl_ddb_entry *entry; enum pipe pipe; @@ -3401,7 +3401,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused) static void drrs_status_per_crtc(struct seq_file *m, struct drm_device *dev, struct intel_crtc *intel_crtc) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_drrs *drrs = &dev_priv->drrs; int vrefresh = 0; struct drm_connector *connector; @@ -3528,7 +3528,7 @@ static int i915_dp_mst_info(struct seq_file *m, void *unused) static int i915_pipe_crc_open(struct inode *inode, struct file *filep) { struct pipe_crc_info *info = inode->i_private; - struct drm_i915_private *dev_priv = info->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(info->dev); struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe]; if (info->pipe >= INTEL_INFO(info->dev)->num_pipes) @@ -3552,7 +3552,7 @@ static int i915_pipe_crc_open(struct inode *inode, struct file *filep) static int i915_pipe_crc_release(struct inode *inode, struct file *filep) { struct pipe_crc_info *info = inode->i_private; - struct drm_i915_private *dev_priv = info->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(info->dev); struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe]; spin_lock_irq(&pipe_crc->lock); @@ -3580,7 +3580,7 @@ i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count, { struct pipe_crc_info *info = filep->private_data; struct drm_device *dev = info->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe]; char buf[PIPE_CRC_BUFFER_LEN]; int n_entries; @@ -3713,7 +3713,7 @@ static const char *pipe_crc_source_name(enum intel_pipe_crc_source source) static int display_crc_ctl_show(struct seq_file *m, void *data) { struct drm_device *dev = m->private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; for (i = 0; i < I915_MAX_PIPES; i++) @@ -3807,7 +3807,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_device *dev, enum intel_pipe_crc_source *source, uint32_t *val) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); bool need_stable_symbols = false; if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) { @@ -3878,7 +3878,7 @@ static int i9xx_pipe_crc_ctl_reg(struct drm_device *dev, enum intel_pipe_crc_source *source, uint32_t *val) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); bool need_stable_symbols = false; if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) { @@ -3952,7 +3952,7 @@ static int i9xx_pipe_crc_ctl_reg(struct drm_device *dev, static void vlv_undo_pipe_scramble_reset(struct drm_device *dev, enum pipe pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t tmp = I915_READ(PORT_DFT2_G4X); switch (pipe) { @@ -3977,7 +3977,7 @@ static void vlv_undo_pipe_scramble_reset(struct drm_device *dev, static void g4x_undo_pipe_scramble_reset(struct drm_device *dev, enum pipe pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t tmp = I915_READ(PORT_DFT2_G4X); if (pipe == PIPE_A) @@ -4020,7 +4020,7 @@ static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, static void hsw_trans_edp_pipe_A_crc_wa(struct drm_device *dev, bool enable) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]); struct intel_crtc_state *pipe_config; @@ -4088,7 +4088,7 @@ static int ivb_pipe_crc_ctl_reg(struct drm_device *dev, static int pipe_crc_set_source(struct drm_device *dev, enum pipe pipe, enum intel_pipe_crc_source source) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; struct intel_crtc *crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); @@ -4595,7 +4595,7 @@ static void wm_latency_show(struct seq_file *m, const uint16_t wm[8]) static int pri_wm_latency_show(struct seq_file *m, void *data) { struct drm_device *dev = m->private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const uint16_t *latencies; if (INTEL_INFO(dev)->gen >= 9) @@ -4611,7 +4611,7 @@ static int pri_wm_latency_show(struct seq_file *m, void *data) static int spr_wm_latency_show(struct seq_file *m, void *data) { struct drm_device *dev = m->private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const uint16_t *latencies; if (INTEL_INFO(dev)->gen >= 9) @@ -4627,7 +4627,7 @@ static int spr_wm_latency_show(struct seq_file *m, void *data) static int cur_wm_latency_show(struct seq_file *m, void *data) { struct drm_device *dev = m->private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const uint16_t *latencies; if (INTEL_INFO(dev)->gen >= 9) @@ -4718,7 +4718,7 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf, { struct seq_file *m = file->private_data; struct drm_device *dev = m->private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint16_t *latencies; if (INTEL_INFO(dev)->gen >= 9) @@ -4734,7 +4734,7 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf, { struct seq_file *m = file->private_data; struct drm_device *dev = m->private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint16_t *latencies; if (INTEL_INFO(dev)->gen >= 9) @@ -4750,7 +4750,7 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf, { struct seq_file *m = file->private_data; struct drm_device *dev = m->private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint16_t *latencies; if (INTEL_INFO(dev)->gen >= 9) @@ -4792,7 +4792,7 @@ static int i915_wedged_get(void *data, u64 *val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); *val = i915_terminally_wedged(&dev_priv->gpu_error); @@ -4803,7 +4803,7 @@ static int i915_wedged_set(void *data, u64 val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* * There is no safeguard against this debugfs entry colliding @@ -4834,7 +4834,7 @@ static int i915_ring_missed_irq_get(void *data, u64 *val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); *val = dev_priv->gpu_error.missed_irq_rings; return 0; @@ -4844,7 +4844,7 @@ static int i915_ring_missed_irq_set(void *data, u64 val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; /* Lock against concurrent debugfs callers */ @@ -4865,7 +4865,7 @@ static int i915_ring_test_irq_get(void *data, u64 *val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); *val = dev_priv->gpu_error.test_irq_rings; @@ -4876,7 +4876,7 @@ static int i915_ring_test_irq_set(void *data, u64 val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); val &= INTEL_INFO(dev_priv)->ring_mask; DRM_DEBUG_DRIVER("Masking interrupts on rings 0x%08llx\n", val); @@ -4909,7 +4909,7 @@ static int i915_drop_caches_set(void *data, u64 val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; DRM_DEBUG("Dropping caches: 0x%08llx\n", val); @@ -4949,7 +4949,7 @@ static int i915_max_freq_get(void *data, u64 *val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; if (INTEL_INFO(dev)->gen < 6) @@ -4971,7 +4971,7 @@ static int i915_max_freq_set(void *data, u64 val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 hw_max, hw_min; int ret; @@ -5016,7 +5016,7 @@ static int i915_min_freq_get(void *data, u64 *val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; if (INTEL_INFO(dev)->gen < 6) @@ -5038,7 +5038,7 @@ static int i915_min_freq_set(void *data, u64 val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 hw_max, hw_min; int ret; @@ -5083,7 +5083,7 @@ static int i915_cache_sharing_get(void *data, u64 *val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 snpcr; int ret; @@ -5109,7 +5109,7 @@ static int i915_cache_sharing_set(void *data, u64 val) { struct drm_device *dev = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 snpcr; if (!(IS_GEN6(dev) || IS_GEN7(dev))) @@ -5146,7 +5146,7 @@ struct sseu_dev_status { static void cherryview_sseu_device_status(struct drm_device *dev, struct sseu_dev_status *stat) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ss_max = 2; int ss; u32 sig1[ss_max], sig2[ss_max]; @@ -5178,7 +5178,7 @@ static void cherryview_sseu_device_status(struct drm_device *dev, static void gen9_sseu_device_status(struct drm_device *dev, struct sseu_dev_status *stat) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int s_max = 3, ss_max = 4; int s, ss; u32 s_reg[s_max], eu_reg[2*s_max], eu_mask[2]; @@ -5243,7 +5243,7 @@ static void gen9_sseu_device_status(struct drm_device *dev, static void broadwell_sseu_device_status(struct drm_device *dev, struct sseu_dev_status *stat) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int s; u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO); @@ -5322,7 +5322,7 @@ static int i915_sseu_status(struct seq_file *m, void *unused) static int i915_forcewake_open(struct inode *inode, struct file *file) { struct drm_device *dev = inode->i_private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (INTEL_INFO(dev)->gen < 6) return 0; @@ -5336,7 +5336,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file) static int i915_forcewake_release(struct inode *inode, struct file *file) { struct drm_device *dev = inode->i_private; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (INTEL_INFO(dev)->gen < 6) return 0; @@ -5469,7 +5469,7 @@ static const struct i915_debugfs_files { void intel_display_crc_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe; for_each_pipe(dev_priv, pipe) { diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7b9b6f90ca69..695001ffd547 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -144,7 +144,7 @@ static enum intel_pch intel_virt_detect_pch(struct drm_device *dev) static void intel_detect_pch(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct pci_dev *pch = NULL; /* In all current cases, num_pipes is equivalent to the PCH_NOP setting @@ -248,7 +248,7 @@ bool i915_semaphore_is_enabled(struct drm_i915_private *dev_priv) static int i915_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); drm_i915_getparam_t *param = data; int value; @@ -384,7 +384,7 @@ static int i915_getparam(struct drm_device *dev, void *data, static int i915_get_bridge_dev(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); if (!dev_priv->bridge_dev) { @@ -398,7 +398,7 @@ static int i915_get_bridge_dev(struct drm_device *dev) static int intel_alloc_mchbar_resource(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; u32 temp_lo, temp_hi = 0; u64 mchbar_addr; @@ -444,7 +444,7 @@ intel_alloc_mchbar_resource(struct drm_device *dev) static void intel_setup_mchbar(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; u32 temp; bool enabled; @@ -484,7 +484,7 @@ intel_setup_mchbar(struct drm_device *dev) static void intel_teardown_mchbar(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; if (dev_priv->mchbar_need_disable) { @@ -601,7 +601,7 @@ static void i915_gem_fini(struct drm_device *dev) static int i915_load_modeset_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; if (i915_inject_load_failure()) @@ -1671,7 +1671,7 @@ out_free_priv: void i915_driver_unload(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); intel_fbdev_fini(dev); @@ -1797,7 +1797,7 @@ static bool suspend_to_idle(struct drm_i915_private *dev_priv) static int i915_drm_suspend(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); pci_power_t opregion_target_state; int error; @@ -1864,7 +1864,7 @@ out: static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation) { - struct drm_i915_private *dev_priv = drm_dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(drm_dev); bool fw_csr; int ret; @@ -1948,7 +1948,7 @@ int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state) static int i915_drm_resume(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; disable_rpm_wakeref_asserts(dev_priv); @@ -2028,7 +2028,7 @@ static int i915_drm_resume(struct drm_device *dev) static int i915_drm_resume_early(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; /* @@ -2684,7 +2684,7 @@ static int intel_runtime_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6()))) @@ -2788,7 +2788,7 @@ static int intel_runtime_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct drm_device *dev = pci_get_drvdata(pdev); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev))) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 94d68f9c3a08..7a88840b59fa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -128,7 +128,7 @@ i915_gem_wait_for_error(struct i915_gpu_error *error) int i915_mutex_lock_interruptible(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; ret = i915_gem_wait_for_error(&dev_priv->gpu_error); @@ -377,13 +377,13 @@ out: void *i915_gem_object_alloc(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); return kmem_cache_zalloc(dev_priv->objects, GFP_KERNEL); } void i915_gem_object_free(struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); kmem_cache_free(dev_priv->objects, obj); } @@ -636,7 +636,7 @@ i915_gem_gtt_pread(struct drm_device *dev, struct drm_i915_gem_object *obj, uint64_t size, uint64_t data_offset, uint64_t data_ptr) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_ggtt *ggtt = &dev_priv->ggtt; struct drm_mm_node node; char __user *user_data; @@ -1250,7 +1250,7 @@ int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_pwrite *args = data; struct drm_i915_gem_object *obj; int ret; @@ -1761,7 +1761,7 @@ i915_gem_object_wait_rendering__nonblocking(struct drm_i915_gem_object *obj, bool readonly) { struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_request *requests[I915_NUM_ENGINES]; int ret, i, n = 0; @@ -2273,7 +2273,7 @@ i915_gem_get_gtt_alignment(struct drm_device *dev, uint32_t size, static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); int ret; dev_priv->mm.shrinker_no_lock_stealing = true; @@ -2489,7 +2489,7 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) static int i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); int page_count, i; struct address_space *mapping; struct sg_table *st; @@ -2620,7 +2620,7 @@ err_pages: int i915_gem_object_get_pages(struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); const struct drm_i915_gem_object_ops *ops = obj->ops; int ret; @@ -2800,7 +2800,7 @@ i915_gem_init_seqno(struct drm_i915_private *dev_priv, u32 seqno) int i915_gem_set_seqno(struct drm_device *dev, u32 seqno) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; if (seqno == 0) @@ -3182,7 +3182,7 @@ static void i915_gem_reset_engine_cleanup(struct intel_engine_cs *engine) void i915_gem_reset(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; /* @@ -3632,7 +3632,7 @@ static void __i915_vma_iounmap(struct i915_vma *vma) static int __i915_vma_unbind(struct i915_vma *vma, bool wait) { struct drm_i915_gem_object *obj = vma->obj; - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); int ret; if (list_empty(&vma->obj_link)) @@ -4250,7 +4250,7 @@ int i915_gem_get_caching_ioctl(struct drm_device *dev, void *data, int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_caching *args = data; struct drm_i915_gem_object *obj; enum i915_cache_level level; @@ -4444,7 +4444,7 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) static int i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_file_private *file_priv = file->driver_priv; unsigned long recent_enough = jiffies - DRM_I915_THROTTLE_JIFFIES; struct drm_i915_gem_request *request, *target = NULL; @@ -4538,7 +4538,7 @@ i915_gem_object_do_pin(struct drm_i915_gem_object *obj, uint32_t alignment, uint64_t flags) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); struct i915_vma *vma; unsigned bound; int ret; @@ -4702,7 +4702,7 @@ int i915_gem_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_madvise *args = data; struct drm_i915_gem_object *obj; int ret; @@ -4867,7 +4867,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) { struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_vma *vma, *next; intel_runtime_pm_get(dev_priv); @@ -4971,7 +4971,7 @@ void i915_gem_vma_destroy(struct i915_vma *vma) static void i915_gem_stop_engines(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; for_each_engine(engine, dev_priv) @@ -4981,7 +4981,7 @@ i915_gem_stop_engines(struct drm_device *dev) int i915_gem_suspend(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; mutex_lock(&dev->struct_mutex); @@ -5013,7 +5013,7 @@ err: void i915_gem_init_swizzling(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (INTEL_INFO(dev)->gen < 5 || dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE) @@ -5038,7 +5038,7 @@ void i915_gem_init_swizzling(struct drm_device *dev) static void init_unused_ring(struct drm_device *dev, u32 base) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(RING_CTL(base), 0); I915_WRITE(RING_HEAD(base), 0); @@ -5065,7 +5065,7 @@ static void init_unused_rings(struct drm_device *dev) int i915_gem_init_engines(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; ret = intel_init_render_ring_buffer(dev); @@ -5113,7 +5113,7 @@ cleanup_render_ring: int i915_gem_init_hw(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; int ret; @@ -5178,7 +5178,7 @@ out: int i915_gem_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; mutex_lock(&dev->struct_mutex); @@ -5235,7 +5235,7 @@ out_unlock: void i915_gem_cleanup_engines(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; for_each_engine(engine, dev_priv) @@ -5276,7 +5276,7 @@ i915_gem_load_init_fences(struct drm_i915_private *dev_priv) void i915_gem_load_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; dev_priv->objects = @@ -5444,7 +5444,7 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old, u64 i915_gem_obj_offset(struct drm_i915_gem_object *o, struct i915_address_space *vm) { - struct drm_i915_private *dev_priv = o->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(o->base.dev); struct i915_vma *vma; WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base); diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 8e952b1a31b3..b4bba8a76191 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -250,7 +250,7 @@ static struct i915_gem_context * __create_hw_context(struct drm_device *dev, struct drm_i915_file_private *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_gem_context *ctx; int ret; @@ -396,7 +396,7 @@ static void i915_gem_context_unpin(struct i915_gem_context *ctx, void i915_gem_context_reset(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); lockdep_assert_held(&dev->struct_mutex); @@ -412,7 +412,7 @@ void i915_gem_context_reset(struct drm_device *dev) int i915_gem_context_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_gem_context *ctx; /* Init should only be called once per module load. Eventually the @@ -499,7 +499,7 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv) void i915_gem_context_fini(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_gem_context *dctx = dev_priv->kernel_context; lockdep_assert_held(&dev->struct_mutex); @@ -1096,7 +1096,7 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_reset_stats *args = data; struct i915_ctx_hang_stats *hs; struct i915_gem_context *ctx; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 39c53d97833a..3a04d37be4e9 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1142,7 +1142,7 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev, struct drm_i915_gem_request *req) { struct intel_engine_cs *engine = req->engine; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret, i; if (!IS_GEN7(dev) || engine != &dev_priv->engine[RCS]) { @@ -1225,7 +1225,7 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params, { struct drm_device *dev = params->dev; struct intel_engine_cs *engine = params->engine; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u64 exec_start, exec_len; int instp_mode; u32 instp_mask; diff --git a/drivers/gpu/drm/i915/i915_gem_fence.c b/drivers/gpu/drm/i915/i915_gem_fence.c index 2b6bdc267fb5..251d7a95af89 100644 --- a/drivers/gpu/drm/i915/i915_gem_fence.c +++ b/drivers/gpu/drm/i915/i915_gem_fence.c @@ -58,7 +58,7 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t fence_reg_lo, fence_reg_hi; int fence_pitch_shift; @@ -117,7 +117,7 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, static void i915_write_fence_reg(struct drm_device *dev, int reg, struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val; if (obj) { @@ -156,7 +156,7 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg, static void i830_write_fence_reg(struct drm_device *dev, int reg, struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t val; if (obj) { @@ -193,7 +193,7 @@ inline static bool i915_gem_object_needs_mb(struct drm_i915_gem_object *obj) static void i915_gem_write_fence(struct drm_device *dev, int reg, struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* Ensure that all CPU reads are completed before installing a fence * and all writes before removing the fence. @@ -229,7 +229,7 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, struct drm_i915_fence_reg *fence, bool enable) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); int reg = fence_number(dev_priv, fence); i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); @@ -286,7 +286,7 @@ i915_gem_object_wait_fence(struct drm_i915_gem_object *obj) int i915_gem_object_put_fence(struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); struct drm_i915_fence_reg *fence; int ret; @@ -311,7 +311,7 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj) static struct drm_i915_fence_reg * i915_find_fence_reg(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_fence_reg *reg, *avail; int i; @@ -367,7 +367,7 @@ int i915_gem_object_get_fence(struct drm_i915_gem_object *obj) { struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); bool enable = obj->tiling_mode != I915_TILING_NONE; struct drm_i915_fence_reg *reg; int ret; @@ -433,7 +433,7 @@ bool i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) { if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); struct i915_vma *ggtt_vma = i915_gem_obj_to_ggtt(obj); WARN_ON(!ggtt_vma || @@ -457,7 +457,7 @@ void i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) { if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count <= 0); dev_priv->fence_regs[obj->fence_reg].pin_count--; } @@ -472,7 +472,7 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) */ void i915_gem_restore_fences(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; for (i = 0; i < dev_priv->num_fence_regs; i++) { @@ -549,7 +549,7 @@ void i915_gem_restore_fences(struct drm_device *dev) void i915_gem_detect_bit_6_swizzle(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 0bb18b88dc7a..cf6fdcb147c6 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1732,7 +1732,7 @@ static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt, { struct intel_engine_cs *engine = req->engine; struct drm_device *dev = ppgtt->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G); @@ -1745,7 +1745,7 @@ static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt, static void gen8_ppgtt_enable(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; for_each_engine(engine, dev_priv) { @@ -1757,7 +1757,7 @@ static void gen8_ppgtt_enable(struct drm_device *dev) static void gen7_ppgtt_enable(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine; uint32_t ecochk, ecobits; @@ -1782,7 +1782,7 @@ static void gen7_ppgtt_enable(struct drm_device *dev) static void gen6_ppgtt_enable(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t ecochk, gab_ctl, ecobits; ecobits = I915_READ(GAC_ECO_BITS); @@ -2142,7 +2142,7 @@ static void i915_address_space_init(struct i915_address_space *vm, static void gtt_write_workarounds(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* This function is for gtt related workarounds. This function is * called on driver load and after a GPU reset, so you can place @@ -2161,7 +2161,7 @@ static void gtt_write_workarounds(struct drm_device *dev) static int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; ret = __hw_ppgtt_init(dev, ppgtt); @@ -2611,7 +2611,7 @@ static void i915_ggtt_insert_entries(struct i915_address_space *vm, uint64_t start, enum i915_cache_level cache_level, u32 unused) { - struct drm_i915_private *dev_priv = vm->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(vm->dev); unsigned int flags = (cache_level == I915_CACHE_NONE) ? AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY; int rpm_atomic_seq; @@ -2629,7 +2629,7 @@ static void i915_ggtt_clear_range(struct i915_address_space *vm, uint64_t length, bool unused) { - struct drm_i915_private *dev_priv = vm->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(vm->dev); unsigned first_entry = start >> PAGE_SHIFT; unsigned num_entries = length >> PAGE_SHIFT; int rpm_atomic_seq; @@ -2710,7 +2710,7 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma, static void ggtt_unbind_vma(struct i915_vma *vma) { struct drm_device *dev = vma->vm->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj = vma->obj; const uint64_t size = min_t(uint64_t, obj->base.size, @@ -2736,7 +2736,7 @@ static void ggtt_unbind_vma(struct i915_vma *vma) void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj) { struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); bool interruptible; interruptible = do_idling(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index e9cd82290408..66be299a1486 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -270,7 +270,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) void i915_gem_cleanup_stolen(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!drm_mm_initialized(&dev_priv->mm.stolen)) return; @@ -550,7 +550,7 @@ static void i915_gem_object_put_pages_stolen(struct drm_i915_gem_object *obj) static void i915_gem_object_release_stolen(struct drm_i915_gem_object *obj) { - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); if (obj->stolen) { i915_gem_stolen_remove_node(dev_priv, obj->stolen); @@ -601,7 +601,7 @@ cleanup: struct drm_i915_gem_object * i915_gem_object_create_stolen(struct drm_device *dev, u32 size) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; struct drm_mm_node *stolen; int ret; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index a6eb5c47a49c..8030199731db 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -162,7 +162,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_gem_set_tiling *args = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; int ret = 0; @@ -294,7 +294,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_gem_get_tiling *args = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; obj = to_intel_bo(drm_gem_object_lookup(file, args->handle)); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index c6e05cccbedf..1d9aa3e6a334 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -332,7 +332,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, const struct i915_error_state_file_priv *error_priv) { struct drm_device *dev = error_priv->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_error_state *error = error_priv->error; struct drm_i915_error_object *obj; int i, j, offset, elt; @@ -1451,7 +1451,7 @@ void i915_capture_error_state(struct drm_i915_private *dev_priv, void i915_error_state_get(struct drm_device *dev, struct i915_error_state_file_priv *error_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); spin_lock_irq(&dev_priv->gpu_error.lock); error_priv->error = dev_priv->gpu_error.first_error; @@ -1469,7 +1469,7 @@ void i915_error_state_put(struct i915_error_state_file_priv *error_priv) void i915_destroy_error_state(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_error_state *error; spin_lock_irq(&dev_priv->gpu_error.lock); diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 355b6475e74c..3f9e3fe98faf 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -1033,7 +1033,7 @@ void i915_guc_submission_fini(struct drm_i915_private *dev_priv) */ int intel_guc_suspend(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_guc *guc = &dev_priv->guc; struct i915_gem_context *ctx; u32 data[3]; @@ -1059,7 +1059,7 @@ int intel_guc_suspend(struct drm_device *dev) */ int intel_guc_resume(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_guc *guc = &dev_priv->guc; struct i915_gem_context *ctx; u32 data[3]; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f0535df41dfd..f6de8dd567a2 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -667,7 +667,7 @@ static u32 i8xx_get_vblank_counter(struct drm_device *dev, unsigned int pipe) */ static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t high_frame, low_frame; u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal; struct intel_crtc *intel_crtc = @@ -714,7 +714,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, unsigned int pipe) static u32 g4x_get_vblank_counter(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); return I915_READ(PIPE_FRMCOUNT_G4X(pipe)); } @@ -723,7 +723,7 @@ static u32 g4x_get_vblank_counter(struct drm_device *dev, unsigned int pipe) static int __intel_get_crtc_scanline(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const struct drm_display_mode *mode = &crtc->base.hwmode; enum pipe pipe = crtc->pipe; int position, vtotal; @@ -775,7 +775,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int position; @@ -896,7 +896,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, int intel_get_crtc_scanline(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); unsigned long irqflags; int position; @@ -1744,7 +1744,7 @@ static void i9xx_hpd_irq_handler(struct drm_i915_private *dev_priv, static irqreturn_t valleyview_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) @@ -1827,7 +1827,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) static irqreturn_t cherryview_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) @@ -2212,7 +2212,7 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv, static irqreturn_t ironlake_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 de_iir, gt_iir, de_ier, sde_ier = 0; irqreturn_t ret = IRQ_NONE; @@ -2444,7 +2444,7 @@ 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 = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 master_ctl; u32 gt_iir[4] = {}; irqreturn_t ret; @@ -2701,7 +2701,7 @@ void i915_handle_error(struct drm_i915_private *dev_priv, */ static int i915_enable_vblank(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); @@ -2718,7 +2718,7 @@ static int i915_enable_vblank(struct drm_device *dev, unsigned int pipe) static int ironlake_enable_vblank(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); @@ -2732,7 +2732,7 @@ static int ironlake_enable_vblank(struct drm_device *dev, unsigned int pipe) static int valleyview_enable_vblank(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); @@ -2745,7 +2745,7 @@ static int valleyview_enable_vblank(struct drm_device *dev, unsigned int pipe) static int gen8_enable_vblank(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); @@ -2760,7 +2760,7 @@ static int gen8_enable_vblank(struct drm_device *dev, unsigned int pipe) */ static void i915_disable_vblank(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); @@ -2772,7 +2772,7 @@ static void i915_disable_vblank(struct drm_device *dev, unsigned int pipe) static void ironlake_disable_vblank(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; uint32_t bit = (INTEL_INFO(dev)->gen >= 7) ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); @@ -2784,7 +2784,7 @@ static void ironlake_disable_vblank(struct drm_device *dev, unsigned int pipe) static void valleyview_disable_vblank(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); @@ -2795,7 +2795,7 @@ static void valleyview_disable_vblank(struct drm_device *dev, unsigned int pipe) static void gen8_disable_vblank(struct drm_device *dev, unsigned int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); @@ -3214,7 +3214,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) static void ibx_irq_reset(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (HAS_PCH_NOP(dev)) return; @@ -3235,7 +3235,7 @@ static void ibx_irq_reset(struct drm_device *dev) */ static void ibx_irq_pre_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (HAS_PCH_NOP(dev)) return; @@ -3247,7 +3247,7 @@ static void ibx_irq_pre_postinstall(struct drm_device *dev) static void gen5_gt_irq_reset(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); GEN5_IRQ_RESET(GT); if (INTEL_INFO(dev)->gen >= 6) @@ -3307,7 +3307,7 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) */ static void ironlake_irq_reset(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(HWSTAM, 0xffffffff); @@ -3322,7 +3322,7 @@ static void ironlake_irq_reset(struct drm_device *dev) static void valleyview_irq_preinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(VLV_MASTER_IER, 0); POSTING_READ(VLV_MASTER_IER); @@ -3345,7 +3345,7 @@ static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv) static void gen8_irq_reset(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe; I915_WRITE(GEN8_MASTER_IRQ, 0); @@ -3396,7 +3396,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, static void cherryview_irq_preinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(GEN8_MASTER_IRQ, 0); POSTING_READ(GEN8_MASTER_IRQ); @@ -3548,7 +3548,7 @@ static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv) static void ibx_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 mask; if (HAS_PCH_NOP(dev)) @@ -3565,7 +3565,7 @@ static void ibx_irq_postinstall(struct drm_device *dev) static void gen5_gt_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 pm_irqs, gt_irqs; pm_irqs = gt_irqs = 0; @@ -3601,7 +3601,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) static int ironlake_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 display_mask, extra_mask; if (INTEL_INFO(dev)->gen >= 7) { @@ -3680,7 +3680,7 @@ void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) static int valleyview_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); gen5_gt_irq_postinstall(dev); @@ -3773,7 +3773,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) static int gen8_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (HAS_PCH_SPLIT(dev)) ibx_irq_pre_postinstall(dev); @@ -3792,7 +3792,7 @@ static int gen8_irq_postinstall(struct drm_device *dev) static int cherryview_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); gen8_gt_irq_postinstall(dev_priv); @@ -3809,7 +3809,7 @@ static int cherryview_irq_postinstall(struct drm_device *dev) static void gen8_irq_uninstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!dev_priv) return; @@ -3819,7 +3819,7 @@ static void gen8_irq_uninstall(struct drm_device *dev) static void valleyview_irq_uninstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!dev_priv) return; @@ -3839,7 +3839,7 @@ static void valleyview_irq_uninstall(struct drm_device *dev) static void cherryview_irq_uninstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!dev_priv) return; @@ -3859,7 +3859,7 @@ static void cherryview_irq_uninstall(struct drm_device *dev) static void ironlake_irq_uninstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!dev_priv) return; @@ -3869,7 +3869,7 @@ static void ironlake_irq_uninstall(struct drm_device *dev) static void i8xx_irq_preinstall(struct drm_device * dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe; for_each_pipe(dev_priv, pipe) @@ -3881,7 +3881,7 @@ static void i8xx_irq_preinstall(struct drm_device * dev) static int i8xx_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE16(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); @@ -3944,7 +3944,7 @@ check_page_flip: static irqreturn_t i8xx_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u16 iir, new_iir; u32 pipe_stats[2]; int pipe; @@ -4021,7 +4021,7 @@ out: static void i8xx_irq_uninstall(struct drm_device * dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe; for_each_pipe(dev_priv, pipe) { @@ -4036,7 +4036,7 @@ static void i8xx_irq_uninstall(struct drm_device * dev) static void i915_irq_preinstall(struct drm_device * dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe; if (I915_HAS_HOTPLUG(dev)) { @@ -4054,7 +4054,7 @@ static void i915_irq_preinstall(struct drm_device * dev) static int i915_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 enable_mask; I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | I915_ERROR_MEMORY_REFRESH)); @@ -4133,7 +4133,7 @@ check_page_flip: static irqreturn_t i915_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 iir, new_iir, pipe_stats[I915_MAX_PIPES]; u32 flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT | @@ -4238,7 +4238,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) static void i915_irq_uninstall(struct drm_device * dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe; if (I915_HAS_HOTPLUG(dev)) { @@ -4260,7 +4260,7 @@ static void i915_irq_uninstall(struct drm_device * dev) static void i965_irq_preinstall(struct drm_device * dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe; i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); @@ -4276,7 +4276,7 @@ static void i965_irq_preinstall(struct drm_device * dev) static int i965_irq_postinstall(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 enable_mask; u32 error_mask; @@ -4360,7 +4360,7 @@ static void i915_hpd_irq_setup(struct drm_i915_private *dev_priv) static irqreturn_t i965_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 iir, new_iir; u32 pipe_stats[I915_MAX_PIPES]; int ret = IRQ_NONE, pipe; @@ -4469,7 +4469,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) static void i965_irq_uninstall(struct drm_device * dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe; if (!dev_priv) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 34e061a9ef06..5cfe4c7716b4 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -31,7 +31,7 @@ static void i915_save_display(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* Display arbitration control */ if (INTEL_INFO(dev)->gen <= 4) @@ -63,7 +63,7 @@ static void i915_save_display(struct drm_device *dev) static void i915_restore_display(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 mask = 0xffffffff; /* Display arbitration */ @@ -103,7 +103,7 @@ static void i915_restore_display(struct drm_device *dev) int i915_save_state(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; mutex_lock(&dev->struct_mutex); @@ -148,7 +148,7 @@ int i915_save_state(struct drm_device *dev) int i915_restore_state(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index a6e90fe05a1e..d61829e54f93 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -38,7 +38,7 @@ static u32 calc_residency(struct drm_device *dev, i915_reg_t reg) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u64 raw_time; /* 32b value may overflow during fixed point math */ u64 units = 128ULL, div = 100000ULL; u32 ret; @@ -166,7 +166,7 @@ i915_l3_read(struct file *filp, struct kobject *kobj, struct device *dev = kobj_to_dev(kobj); struct drm_minor *dminor = dev_to_drm_minor(dev); struct drm_device *drm_dev = dminor->dev; - struct drm_i915_private *dev_priv = drm_dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(drm_dev); int slice = (int)(uintptr_t)attr->private; int ret; @@ -202,7 +202,7 @@ i915_l3_write(struct file *filp, struct kobject *kobj, struct device *dev = kobj_to_dev(kobj); struct drm_minor *dminor = dev_to_drm_minor(dev); struct drm_device *drm_dev = dminor->dev; - struct drm_i915_private *dev_priv = drm_dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(drm_dev); struct i915_gem_context *ctx; u32 *temp = NULL; /* Just here to make handling failures easy */ int slice = (int)(uintptr_t)attr->private; @@ -268,7 +268,7 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev, { struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; flush_delayed_work(&dev_priv->rps.delayed_resume_work); @@ -302,7 +302,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, { struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; flush_delayed_work(&dev_priv->rps.delayed_resume_work); @@ -323,7 +323,7 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev, { struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); return snprintf(buf, PAGE_SIZE, "%d\n", @@ -334,7 +334,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute { struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; flush_delayed_work(&dev_priv->rps.delayed_resume_work); @@ -352,7 +352,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, { struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val; ssize_t ret; @@ -402,7 +402,7 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute { struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; flush_delayed_work(&dev_priv->rps.delayed_resume_work); @@ -420,7 +420,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, { struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val; ssize_t ret; @@ -480,7 +480,7 @@ static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr { struct drm_minor *minor = dev_to_drm_minor(kdev); struct drm_device *dev = minor->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val; if (attr == &dev_attr_gt_RP0_freq_mhz) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index b9329c2a670a..e2e4d4c59e85 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -165,7 +165,7 @@ static bool intel_eld_uptodate(struct drm_connector *connector, i915_reg_t reg_elda, uint32_t bits_elda, i915_reg_t reg_edid) { - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); uint8_t *eld = connector->eld; uint32_t tmp; int i; @@ -189,7 +189,7 @@ static bool intel_eld_uptodate(struct drm_connector *connector, static void g4x_audio_codec_disable(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); uint32_t eldv, tmp; DRM_DEBUG_KMS("Disable audio codec\n"); @@ -210,7 +210,7 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, struct intel_encoder *encoder, const struct drm_display_mode *adjusted_mode) { - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); uint8_t *eld = connector->eld; uint32_t eldv; uint32_t tmp; @@ -247,7 +247,7 @@ static void g4x_audio_codec_enable(struct drm_connector *connector, static void hsw_audio_codec_disable(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum pipe pipe = intel_crtc->pipe; uint32_t tmp; @@ -279,7 +279,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, struct intel_encoder *encoder, const struct drm_display_mode *adjusted_mode) { - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum pipe pipe = intel_crtc->pipe; struct i915_audio_component *acomp = dev_priv->audio_component; @@ -357,7 +357,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, static void ilk_audio_codec_disable(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base); @@ -405,7 +405,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, struct intel_encoder *encoder, const struct drm_display_mode *adjusted_mode) { - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base); @@ -496,7 +496,7 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder) const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; struct drm_connector *connector; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_audio_component *acomp = dev_priv->audio_component; struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); enum port port = intel_dig_port->port; @@ -543,7 +543,7 @@ void intel_audio_codec_disable(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_audio_component *acomp = dev_priv->audio_component; struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); enum port port = intel_dig_port->port; diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 522f5a2de015..2523a5b86dbe 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -96,7 +96,7 @@ static void i9xx_load_csc_matrix(struct drm_crtc_state *crtc_state) { struct drm_crtc *crtc = crtc_state->crtc; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int i, pipe = intel_crtc->pipe; uint16_t coeffs[9] = { 0, }; @@ -207,7 +207,7 @@ static void cherryview_load_csc_matrix(struct drm_crtc_state *state) { struct drm_crtc *crtc = state->crtc; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = to_intel_crtc(crtc)->pipe; uint32_t mode; @@ -255,7 +255,7 @@ static void cherryview_load_csc_matrix(struct drm_crtc_state *state) void intel_color_set_csc(struct drm_crtc_state *crtc_state) { struct drm_device *dev = crtc_state->crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (dev_priv->display.load_csc_matrix) dev_priv->display.load_csc_matrix(crtc_state); @@ -266,7 +266,7 @@ static void i9xx_load_luts_internal(struct drm_crtc *crtc, struct drm_property_blob *blob) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; int i; @@ -313,7 +313,7 @@ static void haswell_load_luts(struct drm_crtc_state *crtc_state) { struct drm_crtc *crtc = crtc_state->crtc; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc_state *intel_crtc_state = to_intel_crtc_state(crtc_state); @@ -343,7 +343,7 @@ static void broadwell_load_luts(struct drm_crtc_state *state) { struct drm_crtc *crtc = state->crtc; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc_state *intel_state = to_intel_crtc_state(state); enum pipe pipe = to_intel_crtc(crtc)->pipe; uint32_t i, lut_size = INTEL_INFO(dev)->color.degamma_lut_size; @@ -426,7 +426,7 @@ static void cherryview_load_luts(struct drm_crtc_state *state) { struct drm_crtc *crtc = state->crtc; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; struct drm_color_lut *lut; uint32_t i, lut_size; @@ -485,7 +485,7 @@ static void cherryview_load_luts(struct drm_crtc_state *state) void intel_color_load_luts(struct drm_crtc_state *crtc_state) { struct drm_device *dev = crtc_state->crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->display.load_luts(crtc_state); } @@ -526,7 +526,7 @@ int intel_color_check(struct drm_crtc *crtc, void intel_color_init(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); drm_mode_crtc_set_gamma_size(crtc, 256); diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 0c8036e1b4d7..5819d524d917 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -67,7 +67,7 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crt *crt = intel_encoder_to_crt(encoder); enum intel_display_power_domain power_domain; u32 tmp; @@ -98,7 +98,7 @@ out: static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crt *crt = intel_encoder_to_crt(encoder); u32 tmp, flags = 0; @@ -146,7 +146,7 @@ static void hsw_crt_get_config(struct intel_encoder *encoder, static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crt *crt = intel_encoder_to_crt(encoder); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; @@ -281,7 +281,7 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct intel_crt *crt = intel_attached_crt(connector); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 adpa; bool ret; @@ -328,7 +328,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct intel_crt *crt = intel_attached_crt(connector); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 adpa; bool ret; u32 save_adpa; @@ -371,7 +371,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) static bool intel_crt_detect_hotplug(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 stat; bool ret = false; int i, tries = 0; @@ -453,7 +453,7 @@ static int intel_crt_ddc_get_modes(struct drm_connector *connector, static bool intel_crt_detect_ddc(struct drm_connector *connector) { struct intel_crt *crt = intel_attached_crt(connector); - struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crt->base.base.dev); struct edid *edid; struct i2c_adapter *i2c; @@ -489,7 +489,7 @@ static enum drm_connector_status intel_crt_load_detect(struct intel_crt *crt, uint32_t pipe) { struct drm_device *dev = crt->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t save_bclrpat; uint32_t save_vtotal; uint32_t vtotal, vactive; @@ -604,7 +604,7 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crt *crt = intel_attached_crt(connector); struct intel_encoder *intel_encoder = &crt->base; enum intel_display_power_domain power_domain; @@ -685,7 +685,7 @@ static void intel_crt_destroy(struct drm_connector *connector) static int intel_crt_get_modes(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crt *crt = intel_attached_crt(connector); struct intel_encoder *intel_encoder = &crt->base; enum intel_display_power_domain power_domain; @@ -720,7 +720,7 @@ static int intel_crt_set_property(struct drm_connector *connector, static void intel_crt_reset(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crt *crt = intel_attached_crt(connector); if (INTEL_INFO(dev)->gen >= 5) { @@ -796,7 +796,7 @@ void intel_crt_init(struct drm_device *dev) struct drm_connector *connector; struct intel_crt *crt; struct intel_connector *intel_connector; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t adpa_reg; u32 adpa; diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 6bcd7ffbff43..d6efe8bf813b 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -543,7 +543,7 @@ static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, void hsw_fdi_link_train(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; u32 temp, i, rx_ctl_val; @@ -851,7 +851,7 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) static void skl_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int link_clock = 0; uint32_t dpll_ctl1, dpll; @@ -899,7 +899,7 @@ static void skl_ddi_clock_get(struct intel_encoder *encoder, static void hsw_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int link_clock = 0; u32 val, pll; @@ -971,7 +971,7 @@ static int bxt_calc_pll_link(struct drm_i915_private *dev_priv, static void bxt_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = intel_ddi_get_encoder_port(encoder); uint32_t dpll = port; @@ -1061,7 +1061,7 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc, void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; @@ -1096,7 +1096,7 @@ void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; uint32_t temp; temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); @@ -1113,7 +1113,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = intel_crtc->pipe; enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; enum port port = intel_ddi_get_encoder_port(intel_encoder); @@ -1223,7 +1223,7 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) { struct drm_device *dev = intel_connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *intel_encoder = intel_connector->encoder; int type = intel_connector->base.connector_type; enum port port = intel_ddi_get_encoder_port(intel_encoder); @@ -1285,7 +1285,7 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_ddi_get_encoder_port(encoder); enum intel_display_power_domain power_domain; u32 tmp; @@ -1359,7 +1359,7 @@ void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) { struct drm_crtc *crtc = &intel_crtc->base; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); enum port port = intel_ddi_get_encoder_port(intel_encoder); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; @@ -1371,7 +1371,7 @@ void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) { - struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; if (cpu_transcoder != TRANSCODER_EDP) @@ -1648,7 +1648,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; uint32_t val; @@ -1695,7 +1695,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; @@ -1734,7 +1734,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int type = intel_encoder->type; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (intel_crtc->config->has_audio) { intel_audio_codec_disable(intel_encoder); @@ -2124,7 +2124,7 @@ void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) void intel_ddi_fdi_disable(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); uint32_t val; @@ -2157,7 +2157,7 @@ void intel_ddi_fdi_disable(struct drm_crtc *crtc) void intel_ddi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; struct intel_hdmi *intel_hdmi; @@ -2256,7 +2256,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, static bool intel_ddi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int type = encoder->type; int port = intel_ddi_get_encoder_port(encoder); int ret; @@ -2322,7 +2322,7 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port) void intel_ddi_init(struct drm_device *dev, enum port port) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_digital_port *intel_dig_port; struct intel_encoder *intel_encoder; struct drm_encoder *encoder; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index acb89e7edd61..c3c620b4f589 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1080,7 +1080,7 @@ enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t reg = PIPEDSL(pipe); u32 line1, line2; u32 line_mask; @@ -1116,7 +1116,7 @@ static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe) static void intel_wait_for_pipe_off(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; enum pipe pipe = crtc->pipe; @@ -1656,7 +1656,7 @@ static int intel_num_dvo_pipes(struct drm_device *dev) static void i9xx_enable_pll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t reg = DPLL(crtc->pipe); u32 dpll = crtc->config->dpll_hw_state.dpll; @@ -1728,7 +1728,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) static void i9xx_disable_pll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = crtc->pipe; /* Disable DVO 2x clock on both PLLs if necessary */ @@ -1980,7 +1980,7 @@ static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) static void intel_enable_pipe(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = crtc->pipe; enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; enum pipe pch_transcoder; @@ -2053,7 +2053,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc) */ static void intel_disable_pipe(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; enum pipe pipe = crtc->pipe; i915_reg_t reg; @@ -2264,7 +2264,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) { struct drm_device *dev = fb->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct i915_ggtt_view view; u32 alignment; @@ -2566,7 +2566,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, struct intel_initial_plane_config *plane_config) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *c; struct intel_crtc *i; struct drm_i915_gem_object *obj; @@ -2662,7 +2662,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, const struct intel_plane_state *plane_state) { struct drm_device *dev = primary->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); @@ -2775,7 +2775,7 @@ static void i9xx_disable_primary_plane(struct drm_plane *primary, struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane = intel_crtc->plane; @@ -2792,7 +2792,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary, const struct intel_plane_state *plane_state) { struct drm_device *dev = primary->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); @@ -2920,7 +2920,7 @@ u32 intel_plane_obj_offset(struct intel_plane *intel_plane, static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(SKL_PS_CTRL(intel_crtc->pipe, id), 0); I915_WRITE(SKL_PS_WIN_POS(intel_crtc->pipe, id), 0); @@ -3030,7 +3030,7 @@ static void skylake_update_primary_plane(struct drm_plane *plane, const struct intel_plane_state *plane_state) { struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); @@ -3114,7 +3114,7 @@ static void skylake_disable_primary_plane(struct drm_plane *primary, struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = to_intel_crtc(crtc)->pipe; I915_WRITE(PLANE_CTL(pipe, 0), 0); @@ -3250,7 +3250,7 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *old_crtc_state) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state); @@ -3291,7 +3291,7 @@ static void intel_update_pipe_config(struct intel_crtc *crtc, static void intel_fdi_normal_train(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; i915_reg_t reg; @@ -3334,7 +3334,7 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc) static void ironlake_fdi_link_train(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; i915_reg_t reg; @@ -3435,7 +3435,7 @@ static const int snb_b_fdi_train_param[] = { static void gen6_fdi_link_train(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; i915_reg_t reg; @@ -3568,7 +3568,7 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; i915_reg_t reg; @@ -3687,7 +3687,7 @@ train_done: static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = intel_crtc->pipe; i915_reg_t reg; u32 temp; @@ -3724,7 +3724,7 @@ static void ironlake_fdi_pll_enable(struct intel_crtc *intel_crtc) static void ironlake_fdi_pll_disable(struct intel_crtc *intel_crtc) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = intel_crtc->pipe; i915_reg_t reg; u32 temp; @@ -3754,7 +3754,7 @@ static void ironlake_fdi_pll_disable(struct intel_crtc *intel_crtc) static void ironlake_fdi_disable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; i915_reg_t reg; @@ -3850,7 +3850,7 @@ static void page_flip_completed(struct intel_crtc *intel_crtc) static int intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); long ret; WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue)); @@ -4013,7 +4013,7 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc, enum pipe pch_transcoder) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; I915_WRITE(PCH_TRANS_HTOTAL(pch_transcoder), @@ -4035,7 +4035,7 @@ static void ironlake_pch_transcoder_set_timings(struct intel_crtc *crtc, static void cpt_set_fdi_bc_bifurcation(struct drm_device *dev, bool enable) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t temp; temp = I915_READ(SOUTH_CHICKEN1); @@ -4104,7 +4104,7 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc) static void ironlake_pch_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; u32 temp; @@ -4194,7 +4194,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) static void lpt_pch_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; @@ -4210,7 +4210,7 @@ static void lpt_pch_enable(struct drm_crtc *crtc) static void cpt_verify_modeset(struct drm_device *dev, int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t dslreg = PIPEDSL(pipe); u32 temp; @@ -4388,7 +4388,7 @@ static void skylake_scaler_disable(struct intel_crtc *crtc) static void skylake_pfit_enable(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = crtc->pipe; struct intel_crtc_scaler_state *scaler_state = &crtc->config->scaler_state; @@ -4416,7 +4416,7 @@ static void skylake_pfit_enable(struct intel_crtc *crtc) static void ironlake_pfit_enable(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = crtc->pipe; if (crtc->config->pch_pfit.enabled) { @@ -4437,7 +4437,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc) void hsw_enable_ips(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!crtc->config->ips_enabled) return; @@ -4475,7 +4475,7 @@ void hsw_enable_ips(struct intel_crtc *crtc) void hsw_disable_ips(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!crtc->config->ips_enabled) return; @@ -4503,7 +4503,7 @@ static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc) { if (intel_crtc->overlay) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); mutex_lock(&dev->struct_mutex); dev_priv->mm.interruptible = false; @@ -4531,7 +4531,7 @@ static void intel_post_enable_primary(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; @@ -4563,7 +4563,7 @@ static void intel_pre_disable_primary(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; @@ -4590,7 +4590,7 @@ static void intel_pre_disable_primary_noatomic(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; @@ -4649,7 +4649,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state) { struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->base.state); struct drm_atomic_state *old_state = old_crtc_state->base.state; @@ -4752,7 +4752,7 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc, unsigned plane_mask static void ironlake_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; @@ -4849,7 +4849,7 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc) static void haswell_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe, hsw_workaround_pipe; @@ -4973,7 +4973,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = crtc->pipe; /* To avoid upsetting the power well on haswell only disable the pfit if @@ -4988,7 +4988,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc, bool force) static void ironlake_crtc_disable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; @@ -5051,7 +5051,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) static void haswell_crtc_disable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; @@ -5103,7 +5103,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) static void i9xx_pfit_enable(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc_state *pipe_config = crtc->config; if (!pipe_config->gmch_pfit.control) @@ -5255,7 +5255,7 @@ static unsigned long modeset_get_crtc_power_domains(struct drm_crtc *crtc, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum intel_display_power_domain domain; unsigned long domains, new_domains, old_domains; @@ -5300,7 +5300,7 @@ static int skl_calc_cdclk(int max_pixclk, int vco); static void intel_update_max_cdclk(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) { u32 limit = I915_READ(SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK; @@ -5361,7 +5361,7 @@ static void intel_update_max_cdclk(struct drm_device *dev) static void intel_update_cdclk(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->cdclk_freq = dev_priv->display.get_display_clock_speed(dev); @@ -5887,7 +5887,7 @@ sanitize: /* Adjust CDclk dividers to allow high res or save power if possible */ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val, cmd; WARN_ON(dev_priv->display.get_display_clock_speed(dev) @@ -5952,7 +5952,7 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) static void cherryview_set_cdclk(struct drm_device *dev, int cdclk) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val, cmd; WARN_ON(dev_priv->display.get_display_clock_speed(dev) @@ -6040,7 +6040,7 @@ static int intel_mode_max_pixclk(struct drm_device *dev, struct drm_atomic_state *state) { struct intel_atomic_state *intel_state = to_intel_atomic_state(state); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; unsigned max_pixclk = 0, i; @@ -6067,7 +6067,7 @@ static int intel_mode_max_pixclk(struct drm_device *dev, static int valleyview_modeset_calc_cdclk(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int max_pixclk = intel_mode_max_pixclk(dev, state); struct intel_atomic_state *intel_state = to_intel_atomic_state(state); @@ -6135,7 +6135,7 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) static void valleyview_modeset_commit_cdclk(struct drm_atomic_state *old_state) { struct drm_device *dev = old_state->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_atomic_state *old_intel_state = to_intel_atomic_state(old_state); unsigned req_cdclk = old_intel_state->dev_cdclk; @@ -6181,7 +6181,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) intel_set_pipe_src_size(intel_crtc); if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(CHV_BLEND(pipe), CHV_BLEND_LEGACY); I915_WRITE(CHV_CANVAS(pipe), 0); @@ -6226,7 +6226,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) static void i9xx_set_pll_dividers(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(FP0(crtc->pipe), crtc->config->dpll_hw_state.fp0); I915_WRITE(FP1(crtc->pipe), crtc->config->dpll_hw_state.fp1); @@ -6283,7 +6283,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) static void i9xx_pfit_disable(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!crtc->config->gmch_pfit.control) return; @@ -6298,7 +6298,7 @@ static void i9xx_pfit_disable(struct intel_crtc *crtc) static void i9xx_crtc_disable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; @@ -6642,7 +6642,7 @@ static void hsw_compute_ips_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); pipe_config->ips_enabled = i915.enable_ips && hsw_crtc_supports_ips(crtc) && @@ -6662,7 +6662,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; int clock_limit = dev_priv->max_dotclk_freq; @@ -6812,7 +6812,7 @@ static int broxton_get_display_clock_speed(struct drm_device *dev) static int broadwell_get_display_clock_speed(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t lcpll = I915_READ(LCPLL_CTL); uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; @@ -6832,7 +6832,7 @@ static int broadwell_get_display_clock_speed(struct drm_device *dev) static int haswell_get_display_clock_speed(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t lcpll = I915_READ(LCPLL_CTL); uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; @@ -6966,7 +6966,7 @@ static int i830_get_display_clock_speed(struct drm_device *dev) static unsigned int intel_hpll_vco(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); static const unsigned int blb_vco[8] = { [0] = 3200000, [1] = 4000000, @@ -7246,7 +7246,7 @@ static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, struct intel_link_m_n *m_n) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = crtc->pipe; I915_WRITE(PCH_TRANS_DATA_M1(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); @@ -7260,7 +7260,7 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, struct intel_link_m_n *m2_n2) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = crtc->pipe; enum transcoder transcoder = crtc->config->cpu_transcoder; @@ -7351,7 +7351,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, const struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = crtc->pipe; u32 mdiv; u32 bestn, bestm1, bestm2, bestp1, bestp2; @@ -7451,7 +7451,7 @@ static void chv_prepare_pll(struct intel_crtc *crtc, const struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = crtc->pipe; enum dpio_channel port = vlv_pipe_to_channel(pipe); u32 loopfilter, tribuf_calcntr; @@ -7613,7 +7613,7 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, struct dpll *reduced_clock) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 dpll; bool is_sdvo; struct dpll *clock = &crtc_state->dpll; @@ -7689,7 +7689,7 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc, struct dpll *reduced_clock) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 dpll; struct dpll *clock = &crtc_state->dpll; @@ -7724,7 +7724,7 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc, static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = intel_crtc->pipe; enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; @@ -7786,7 +7786,7 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) static void intel_set_pipe_src_size(struct intel_crtc *intel_crtc) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = intel_crtc->pipe; /* pipesrc controls the size that is scaled from, which should @@ -7801,7 +7801,7 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; uint32_t tmp; @@ -7836,7 +7836,7 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 tmp; tmp = I915_READ(PIPESRC(crtc->pipe)); @@ -7874,7 +7874,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode, static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t pipeconf; pipeconf = 0; @@ -7939,7 +7939,7 @@ static int i8xx_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const struct intel_limit *limit; int refclk = 48000; @@ -7975,7 +7975,7 @@ static int g4x_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const struct intel_limit *limit; int refclk = 96000; @@ -8018,7 +8018,7 @@ static int pnv_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const struct intel_limit *limit; int refclk = 96000; @@ -8052,7 +8052,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const struct intel_limit *limit; int refclk = 96000; @@ -8128,7 +8128,7 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t tmp; if (INTEL_INFO(dev)->gen <= 3 && (IS_I830(dev) || !IS_MOBILE(dev))) @@ -8155,7 +8155,7 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = pipe_config->cpu_transcoder; struct dpll clock; u32 mdiv; @@ -8183,7 +8183,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, struct intel_initial_plane_config *plane_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val, base, offset; int pipe = crtc->pipe, plane = crtc->plane; int fourcc, pixel_format; @@ -8251,7 +8251,7 @@ static void chv_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = pipe_config->cpu_transcoder; enum dpio_channel port = vlv_pipe_to_channel(pipe); struct dpll clock; @@ -8285,7 +8285,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; uint32_t tmp; bool ret; @@ -8396,7 +8396,7 @@ out: static void ironlake_init_pch_refclk(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder; int i; u32 val, final; @@ -8667,7 +8667,7 @@ static void lpt_program_fdi_mphy(struct drm_i915_private *dev_priv) static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread, bool with_fdi) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t reg, tmp; if (WARN(with_fdi && !with_spread, "FDI requires downspread\n")) @@ -8706,7 +8706,7 @@ static void lpt_enable_clkout_dp(struct drm_device *dev, bool with_spread, /* Sequence to disable CLKOUT_DP */ static void lpt_disable_clkout_dp(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t reg, tmp; mutex_lock(&dev_priv->sb_lock); @@ -8827,7 +8827,7 @@ void intel_init_pch_refclk(struct drm_device *dev) static void ironlake_set_pipeconf(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; uint32_t val; @@ -8869,7 +8869,7 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc) static void haswell_set_pipeconf(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; u32 val = 0; @@ -8888,7 +8888,7 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc) static void haswell_set_pipemisc(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) { @@ -8941,7 +8941,7 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, { struct drm_crtc *crtc = &intel_crtc->base; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_atomic_state *state = crtc_state->base.state; struct drm_connector *connector; struct drm_connector_state *connector_state; @@ -9044,7 +9044,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct dpll reduced_clock; bool has_reduced_clock = false; struct intel_shared_dpll *pll; @@ -9110,7 +9110,7 @@ static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc, struct intel_link_m_n *m_n) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = crtc->pipe; m_n->link_m = I915_READ(PCH_TRANS_LINK_M1(pipe)); @@ -9128,7 +9128,7 @@ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc, struct intel_link_m_n *m2_n2) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = crtc->pipe; if (INTEL_INFO(dev)->gen >= 5) { @@ -9186,7 +9186,7 @@ static void skylake_get_pfit_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc_scaler_state *scaler_state = &pipe_config->scaler_state; uint32_t ps_ctrl = 0; int id = -1; @@ -9217,7 +9217,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, struct intel_initial_plane_config *plane_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val, base, offset, stride_mult, tiling; int pipe = crtc->pipe; int fourcc, pixel_format; @@ -9300,7 +9300,7 @@ static void ironlake_get_pfit_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t tmp; tmp = I915_READ(PF_CTL(crtc->pipe)); @@ -9325,7 +9325,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, struct intel_initial_plane_config *plane_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val, base, offset; int pipe = crtc->pipe; int fourcc, pixel_format; @@ -9393,7 +9393,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; uint32_t tmp; bool ret; @@ -9723,7 +9723,7 @@ static void bxt_modeset_commit_cdclk(struct drm_atomic_state *old_state) static int ilk_max_pixel_rate(struct drm_atomic_state *state) { struct intel_atomic_state *intel_state = to_intel_atomic_state(state); - struct drm_i915_private *dev_priv = state->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(state->dev); struct drm_crtc *crtc; struct drm_crtc_state *cstate; struct intel_crtc_state *crtc_state; @@ -9759,7 +9759,7 @@ static int ilk_max_pixel_rate(struct drm_atomic_state *state) static void broadwell_set_cdclk(struct drm_device *dev, int cdclk) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t val, data; int ret; @@ -10041,7 +10041,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, unsigned long *power_domain_mask) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; u32 tmp; @@ -10092,7 +10092,7 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, unsigned long *power_domain_mask) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; enum port port; enum transcoder cpu_transcoder; @@ -10142,7 +10142,7 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_shared_dpll *pll; enum port port; uint32_t tmp; @@ -10185,7 +10185,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; unsigned long power_domain_mask; bool active; @@ -10261,7 +10261,7 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base, const struct intel_plane_state *plane_state) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t cntl = 0, size = 0; @@ -10324,7 +10324,7 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base, const struct intel_plane_state *plane_state) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; uint32_t cntl = 0; @@ -10372,7 +10372,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, const struct intel_plane_state *plane_state) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; u32 base = intel_crtc->cursor_addr; @@ -10539,7 +10539,7 @@ mode_fits_in_fbdev(struct drm_device *dev, struct drm_display_mode *mode) { #ifdef CONFIG_DRM_FBDEV_EMULATION - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_gem_object *obj; struct drm_framebuffer *fb; @@ -10809,7 +10809,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, static int i9xx_pll_refclk(struct drm_device *dev, const struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 dpll = pipe_config->dpll_hw_state.dpll; if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) @@ -10827,7 +10827,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe = pipe_config->cpu_transcoder; u32 dpll = pipe_config->dpll_hw_state.dpll; u32 fp; @@ -10953,7 +10953,7 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc, struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; struct drm_display_mode *mode; @@ -11066,7 +11066,7 @@ static bool __pageflip_finished_cs(struct intel_crtc *crtc, struct intel_flip_work *work) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned reset_counter; reset_counter = i915_reset_counter(&dev_priv->gpu_error); @@ -11277,7 +11277,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev, uint32_t flags) { struct intel_engine_cs *engine = req->engine; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t pf, pipesrc; int ret; @@ -11315,7 +11315,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, uint32_t flags) { struct intel_engine_cs *engine = req->engine; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); uint32_t pf, pipesrc; int ret; @@ -11474,7 +11474,7 @@ static void skl_do_mmio_flip(struct intel_crtc *intel_crtc, struct intel_flip_work *work) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_framebuffer *fb = intel_crtc->base.primary->fb; const enum pipe pipe = intel_crtc->pipe; u32 ctl, stride, tile_height; @@ -11526,7 +11526,7 @@ static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc, struct intel_flip_work *work) { struct drm_device *dev = intel_crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_framebuffer *intel_fb = to_intel_framebuffer(intel_crtc->base.primary->fb); struct drm_i915_gem_object *obj = intel_fb->obj; @@ -11662,7 +11662,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, uint32_t page_flip_flags) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_framebuffer *old_fb = crtc->primary->fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -12099,7 +12099,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc_state); @@ -12960,7 +12960,7 @@ static void verify_wm_state(struct drm_crtc *crtc, struct drm_crtc_state *new_state) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct skl_ddb_allocation hw_ddb, *sw_ddb; struct skl_ddb_entry *hw_entry, *sw_entry; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -13066,7 +13066,7 @@ verify_crtc_state(struct drm_crtc *crtc, struct drm_crtc_state *new_crtc_state) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc_state *pipe_config, *sw_config; @@ -13189,7 +13189,7 @@ verify_shared_dpll_state(struct drm_device *dev, struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state, struct drm_crtc_state *new_crtc_state) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc_state *old_state = to_intel_crtc_state(old_crtc_state); struct intel_crtc_state *new_state = to_intel_crtc_state(new_crtc_state); @@ -13228,7 +13228,7 @@ intel_modeset_verify_crtc(struct drm_crtc *crtc, static void verify_disabled_dpll_state(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; for (i = 0; i < dev_priv->num_shared_dpll; i++) @@ -13410,7 +13410,7 @@ static int intel_modeset_all_pipes(struct drm_atomic_state *state) static int intel_modeset_checks(struct drm_atomic_state *state) { struct intel_atomic_state *intel_state = to_intel_atomic_state(state); - struct drm_i915_private *dev_priv = state->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(state->dev); struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; int ret = 0, i; @@ -13576,7 +13576,7 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_plane_state *plane_state; struct drm_crtc_state *crtc_state; struct drm_plane *plane; @@ -13705,7 +13705,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; struct intel_atomic_state *intel_state = to_intel_atomic_state(state); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc_state *old_crtc_state; struct drm_crtc *crtc; struct intel_crtc_state *intel_cstate; @@ -13937,7 +13937,7 @@ static int intel_atomic_commit(struct drm_device *dev, bool nonblock) { struct intel_atomic_state *intel_state = to_intel_atomic_state(state); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; if (intel_state->modeset && nonblock) { @@ -14542,7 +14542,7 @@ static void skl_init_scalers(struct drm_device *dev, struct intel_crtc *intel_cr static void intel_crtc_init(struct drm_device *dev, int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc; struct intel_crtc_state *crtc_state = NULL; struct drm_plane *primary = NULL; @@ -14669,7 +14669,7 @@ static int intel_encoder_clones(struct intel_encoder *encoder) static bool has_edp_a(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!IS_MOBILE(dev)) return false; @@ -14685,7 +14685,7 @@ static bool has_edp_a(struct drm_device *dev) static bool intel_crt_present(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (INTEL_INFO(dev)->gen >= 9) return false; @@ -14711,7 +14711,7 @@ static bool intel_crt_present(struct drm_device *dev) static void intel_setup_outputs(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder; bool dpd_is_edp = false; @@ -15364,7 +15364,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv) */ static void quirk_pipea_force(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->quirks |= QUIRK_PIPEA_FORCE; DRM_INFO("applying pipe a force quirk\n"); @@ -15372,7 +15372,7 @@ static void quirk_pipea_force(struct drm_device *dev) static void quirk_pipeb_force(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->quirks |= QUIRK_PIPEB_FORCE; DRM_INFO("applying pipe b force quirk\n"); @@ -15383,7 +15383,7 @@ static void quirk_pipeb_force(struct drm_device *dev) */ static void quirk_ssc_force_disable(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE; DRM_INFO("applying lvds SSC disable quirk\n"); } @@ -15394,7 +15394,7 @@ static void quirk_ssc_force_disable(struct drm_device *dev) */ static void quirk_invert_brightness(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS; DRM_INFO("applying inverted panel brightness quirk\n"); } @@ -15402,7 +15402,7 @@ static void quirk_invert_brightness(struct drm_device *dev) /* Some VBT's incorrectly indicate no backlight is present */ static void quirk_backlight_present(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->quirks |= QUIRK_BACKLIGHT_PRESENT; DRM_INFO("applying backlight present quirk\n"); } @@ -15528,7 +15528,7 @@ static void intel_init_quirks(struct drm_device *dev) /* Disable the VGA plane that we never use */ static void i915_disable_vga(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u8 sr1; i915_reg_t vga_reg = i915_vgacntrl_reg(dev); @@ -15546,7 +15546,7 @@ static void i915_disable_vga(struct drm_device *dev) void intel_modeset_init_hw(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); intel_update_cdclk(dev); @@ -15794,7 +15794,7 @@ static bool intel_check_plane_mapping(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val; if (INTEL_INFO(dev)->num_pipes == 1) @@ -15834,7 +15834,7 @@ static bool intel_encoder_has_connectors(struct intel_encoder *encoder) static void intel_sanitize_crtc(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; /* Clear any frame start delays used for debugging left by the BIOS */ @@ -15959,7 +15959,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) void i915_redisable_vga_power_on(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t vga_reg = i915_vgacntrl_reg(dev); if (!(I915_READ(vga_reg) & VGA_DISP_DISABLE)) { @@ -15970,7 +15970,7 @@ void i915_redisable_vga_power_on(struct drm_device *dev) void i915_redisable_vga(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* This function can be called both from intel_modeset_setup_hw_state or * at a very early point in our resume sequence, where the power well @@ -16010,7 +16010,7 @@ static void readout_plane_state(struct intel_crtc *crtc) static void intel_modeset_readout_hw_state(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe; struct intel_crtc *crtc; struct intel_encoder *encoder; @@ -16163,7 +16163,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) static void intel_modeset_setup_hw_state(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe; struct intel_crtc *crtc; struct intel_encoder *encoder; @@ -16346,7 +16346,7 @@ void intel_connector_unregister(struct drm_connector *connector) void intel_modeset_cleanup(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); intel_disable_gt_powersave(dev_priv); @@ -16392,7 +16392,7 @@ void intel_connector_attach_encoder(struct intel_connector *connector, */ int intel_modeset_vga_set_state(struct drm_device *dev, bool state) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned reg = INTEL_INFO(dev)->gen >= 6 ? SNB_GMCH_CTRL : INTEL_GMCH_CTRL; u16 gmch_ctrl; @@ -16548,7 +16548,7 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, struct drm_device *dev, struct intel_display_error_state *error) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; if (!error) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0757ee427ad7..1083f5e2d45b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -262,7 +262,7 @@ static void pps_lock(struct intel_dp *intel_dp) struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &intel_dig_port->base; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; /* @@ -280,7 +280,7 @@ static void pps_unlock(struct intel_dp *intel_dp) struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &intel_dig_port->base; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; mutex_unlock(&dev_priv->pps_mutex); @@ -294,7 +294,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = intel_dp->pps_pipe; bool pll_enabled, release_cl_override = false; enum dpio_phy phy = DPIO_PHY(pipe); @@ -368,7 +368,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder; unsigned int pipes = (1 << PIPE_A) | (1 << PIPE_B); enum pipe pipe; @@ -431,7 +431,7 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); lockdep_assert_held(&dev_priv->pps_mutex); @@ -506,7 +506,7 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_dig_port->port; lockdep_assert_held(&dev_priv->pps_mutex); @@ -639,7 +639,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, struct intel_dp *intel_dp = container_of(this, typeof(* intel_dp), edp_notifier); struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!is_edp(intel_dp) || code != SYS_RESTART) return 0; @@ -670,7 +670,7 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, static bool edp_have_panel_power(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); lockdep_assert_held(&dev_priv->pps_mutex); @@ -684,7 +684,7 @@ static bool edp_have_panel_power(struct intel_dp *intel_dp) static bool edp_have_panel_vdd(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); lockdep_assert_held(&dev_priv->pps_mutex); @@ -699,7 +699,7 @@ static void intel_dp_check_edp(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (!is_edp(intel_dp)) return; @@ -717,7 +717,7 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg; uint32_t status; bool done; @@ -850,7 +850,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg; uint32_t aux_clock_divider; int i, ret, recv_bytes; @@ -1473,7 +1473,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); enum port port = dp_to_dig_port(intel_dp)->port; @@ -1657,7 +1657,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, static void intel_dp_prepare(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); enum port port = dp_to_dig_port(intel_dp)->port; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); @@ -1753,7 +1753,7 @@ static void wait_panel_status(struct intel_dp *intel_dp, u32 value) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t pp_stat_reg, pp_ctrl_reg; lockdep_assert_held(&dev_priv->pps_mutex); @@ -1830,7 +1830,7 @@ static void edp_wait_backlight_off(struct intel_dp *intel_dp) static u32 ironlake_get_pp_control(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 control; lockdep_assert_held(&dev_priv->pps_mutex); @@ -1853,7 +1853,7 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) struct drm_device *dev = intel_dp_to_dev(intel_dp); struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; u32 pp; i915_reg_t pp_stat_reg, pp_ctrl_reg; @@ -1926,7 +1926,7 @@ void intel_edp_panel_vdd_on(struct intel_dp *intel_dp) static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; @@ -1995,8 +1995,7 @@ static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp) */ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) { - struct drm_i915_private *dev_priv = - intel_dp_to_dev(intel_dp)->dev_private; + struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp)); lockdep_assert_held(&dev_priv->pps_mutex); @@ -2017,7 +2016,7 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) static void edp_panel_on(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 pp; i915_reg_t pp_ctrl_reg; @@ -2078,7 +2077,7 @@ static void edp_panel_off(struct intel_dp *intel_dp) struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; u32 pp; i915_reg_t pp_ctrl_reg; @@ -2130,7 +2129,7 @@ static void _intel_edp_backlight_on(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 pp; i915_reg_t pp_ctrl_reg; @@ -2171,7 +2170,7 @@ void intel_edp_backlight_on(struct intel_dp *intel_dp) static void _intel_edp_backlight_off(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 pp; i915_reg_t pp_ctrl_reg; @@ -2352,7 +2351,7 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); enum port port = dp_to_dig_port(intel_dp)->port; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; u32 tmp; bool ret; @@ -2405,7 +2404,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); u32 tmp, flags = 0; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = dp_to_dig_port(intel_dp)->port; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); @@ -2529,7 +2528,7 @@ static void chv_post_disable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); intel_dp_link_down(intel_dp); @@ -2548,7 +2547,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp, { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_dig_port->port; if (HAS_DDI(dev)) { @@ -2628,7 +2627,7 @@ _intel_dp_set_link_train(struct intel_dp *intel_dp, static void intel_dp_enable_port(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(dp_to_dig_port(intel_dp)->base.base.crtc); @@ -2657,7 +2656,7 @@ static void intel_enable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); uint32_t dp_reg = I915_READ(intel_dp->output_reg); enum pipe pipe = crtc->pipe; @@ -2730,7 +2729,7 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder) static void vlv_detach_power_sequencer(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_i915_private *dev_priv = intel_dig_port->base.base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev); enum pipe pipe = intel_dp->pps_pipe; i915_reg_t pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe); @@ -2756,7 +2755,7 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp) static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder; lockdep_assert_held(&dev_priv->pps_mutex); @@ -2794,7 +2793,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &intel_dig_port->base; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); lockdep_assert_held(&dev_priv->pps_mutex); @@ -2882,7 +2881,7 @@ uint8_t intel_dp_voltage_max(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = dp_to_dig_port(intel_dp)->port; if (IS_BROXTON(dev)) @@ -3300,7 +3299,7 @@ void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_dig_port->port; uint32_t val; @@ -3336,7 +3335,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc); enum port port = intel_dig_port->port; struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t DP = intel_dp->DP; if (WARN_ON(HAS_DDI(dev))) @@ -3403,7 +3402,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd, sizeof(intel_dp->dpcd)) < 0) @@ -4418,7 +4417,7 @@ intel_dp_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t val) { - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_encoder *intel_encoder = intel_attached_encoder(connector); struct intel_dp *intel_dp = enc_to_intel_dp(&intel_encoder->base); @@ -4600,7 +4599,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; lockdep_assert_held(&dev_priv->pps_mutex); @@ -4676,7 +4675,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) struct intel_dp *intel_dp = &intel_dig_port->dp; struct intel_encoder *intel_encoder = &intel_dig_port->base; struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; enum irqreturn ret = IRQ_NONE; @@ -4744,7 +4743,7 @@ put_power: /* check the VBT to see whether the eDP is on another port */ bool intel_dp_is_edp(struct drm_device *dev, enum port port) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* * eDP not supported on g4x. so bail out early just @@ -4860,7 +4859,7 @@ static void intel_dp_init_panel_power_sequencer(struct drm_device *dev, struct intel_dp *intel_dp) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct edp_power_seq cur, vbt, spec, *final = &intel_dp->pps_delays; @@ -4932,7 +4931,7 @@ static void intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, struct intel_dp *intel_dp) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 pp_on, pp_off, pp_div, port_sel = 0; int div = dev_priv->rawclk_freq / 1000; struct pps_registers regs; @@ -5002,7 +5001,7 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, */ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder; struct intel_digital_port *dig_port = NULL; struct intel_dp *intel_dp = dev_priv->drrs.dp; @@ -5101,7 +5100,7 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) void intel_edp_drrs_enable(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_crtc *crtc = dig_port->base.base.crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -5133,7 +5132,7 @@ unlock: void intel_edp_drrs_disable(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_crtc *crtc = dig_port->base.base.crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -5201,7 +5200,7 @@ unlock: void intel_edp_drrs_invalidate(struct drm_device *dev, unsigned frontbuffer_bits) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; enum pipe pipe; @@ -5246,7 +5245,7 @@ void intel_edp_drrs_invalidate(struct drm_device *dev, void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; enum pipe pipe; @@ -5339,7 +5338,7 @@ intel_dp_drrs_init(struct intel_connector *intel_connector, { struct drm_connector *connector = &intel_connector->base; struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_display_mode *downclock_mode = NULL; INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work); @@ -5377,7 +5376,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *intel_encoder = &intel_dig_port->base; struct drm_device *dev = intel_encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_display_mode *fixed_mode = NULL; struct drm_display_mode *downclock_mode = NULL; bool has_dpcd; @@ -5519,7 +5518,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, struct intel_dp *intel_dp = &intel_dig_port->dp; struct intel_encoder *intel_encoder = &intel_dig_port->base; struct drm_device *dev = intel_encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_dig_port->port; int type; @@ -5650,7 +5649,7 @@ bool intel_dp_init(struct drm_device *dev, i915_reg_t output_reg, enum port port) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_digital_port *intel_dig_port; struct intel_encoder *intel_encoder; struct drm_encoder *encoder; @@ -5728,7 +5727,7 @@ err_connector_alloc: void intel_dp_mst_suspend(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; /* disable MST */ @@ -5748,7 +5747,7 @@ void intel_dp_mst_suspend(struct drm_device *dev) void intel_dp_mst_resume(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int i; for (i = 0; i < I915_MAX_PORTS; i++) { diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index c1d318601bf1..81800877b1af 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -140,7 +140,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_dig_port->port; int ret; uint32_t temp; @@ -207,7 +207,7 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder) struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_dig_port->port; int ret; @@ -242,7 +242,7 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; u32 temp, flags = 0; diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c index 288da35572b4..047f48748944 100644 --- a/drivers/gpu/drm/i915/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/intel_dpio_phy.c @@ -168,7 +168,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder) { struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum dpio_channel ch = vlv_dport_to_channel(dport); @@ -250,7 +250,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder) struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); struct intel_digital_port *dport = dp_to_dig_port(intel_dp); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum dpio_channel ch = vlv_dport_to_channel(dport); @@ -400,7 +400,7 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder) { struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum dpio_channel port = vlv_dport_to_channel(dport); @@ -429,7 +429,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder) struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); struct intel_digital_port *dport = dp_to_dig_port(intel_dp); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum dpio_channel port = vlv_dport_to_channel(dport); int pipe = intel_crtc->pipe; @@ -457,7 +457,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder) void vlv_phy_reset_lanes(struct intel_encoder *encoder) { struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum dpio_channel port = vlv_dport_to_channel(dport); diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index e19757c76db6..8a4dac98b3d5 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -83,7 +83,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv, void intel_prepare_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_shared_dpll *pll = crtc->config->shared_dpll; if (WARN_ON(pll == NULL)) @@ -112,7 +112,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc) void intel_enable_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_shared_dpll *pll = crtc->config->shared_dpll; unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base); unsigned old_mask; @@ -151,7 +151,7 @@ out: void intel_disable_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_shared_dpll *pll = crtc->config->shared_dpll; unsigned crtc_mask = 1 << drm_crtc_index(&crtc->base); @@ -191,7 +191,7 @@ intel_find_shared_dpll(struct intel_crtc *crtc, enum intel_dpll_id range_min, enum intel_dpll_id range_max) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; struct intel_shared_dpll_config *shared_dpll; enum intel_dpll_id i; @@ -1636,7 +1636,7 @@ static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = { static void intel_ddi_pll_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (INTEL_GEN(dev_priv) < 9) { uint32_t val = I915_READ(LCPLL_CTL); @@ -1723,7 +1723,7 @@ static const struct intel_dpll_mgr bxt_pll_mgr = { void intel_shared_dpll_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const struct intel_dpll_mgr *dpll_mgr = NULL; const struct dpll_info *dpll_info; int i; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 98a5be4ec8c5..e6a24d2154d1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -987,14 +987,14 @@ vlv_pipe_to_channel(enum pipe pipe) static inline struct drm_crtc * intel_get_crtc_for_pipe(struct drm_device *dev, int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); return dev_priv->pipe_to_crtc_mapping[pipe]; } static inline struct drm_crtc * intel_get_crtc_for_plane(struct drm_device *dev, int plane) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); return dev_priv->plane_to_crtc_mapping[plane]; } diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 448741d8653b..51109ac945bf 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -84,7 +84,7 @@ static void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi, enum port port) { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 mask; mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY | @@ -131,7 +131,7 @@ static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host, { struct intel_dsi_host *intel_dsi_host = to_intel_dsi_host(host); struct drm_device *dev = intel_dsi_host->intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_dsi_host->port; struct mipi_dsi_packet packet; ssize_t ret; @@ -260,7 +260,7 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs, { struct drm_encoder *encoder = &intel_dsi->base.base; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 mask; /* XXX: pipe, hs */ @@ -314,7 +314,7 @@ static inline bool is_cmd_mode(struct intel_dsi *intel_dsi) static bool intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi, base); struct intel_connector *intel_connector = intel_dsi->attached_connector; @@ -360,7 +360,7 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, static void bxt_dsi_device_ready(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; u32 val; @@ -399,7 +399,7 @@ static void bxt_dsi_device_ready(struct intel_encoder *encoder) static void vlv_dsi_device_ready(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; u32 val; @@ -449,7 +449,7 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) static void intel_dsi_port_enable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; @@ -490,7 +490,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder) static void intel_dsi_port_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; @@ -509,7 +509,7 @@ static void intel_dsi_port_disable(struct intel_encoder *encoder) static void intel_dsi_enable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; @@ -540,7 +540,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder); static void intel_dsi_pre_enable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); enum port port; @@ -614,7 +614,7 @@ static void intel_dsi_pre_disable(struct intel_encoder *encoder) static void intel_dsi_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; u32 temp; @@ -653,7 +653,7 @@ static void intel_dsi_disable(struct intel_encoder *encoder) static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; @@ -698,7 +698,7 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) static void intel_dsi_post_disable(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); DRM_DEBUG_KMS("\n"); @@ -733,7 +733,7 @@ static void intel_dsi_post_disable(struct intel_encoder *encoder) static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); struct drm_device *dev = encoder->base.dev; enum intel_display_power_domain power_domain; @@ -807,7 +807,7 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; struct drm_display_mode *adjusted_mode_sw; @@ -1026,7 +1026,7 @@ static void set_dsi_timings(struct drm_encoder *encoder, const struct drm_display_mode *adjusted_mode) { struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); @@ -1112,7 +1112,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; @@ -1434,7 +1434,7 @@ void intel_dsi_init(struct drm_device *dev) struct intel_connector *intel_connector; struct drm_connector *connector; struct drm_display_mode *scan, *fixed_mode = NULL; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port; unsigned int i; diff --git a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c index f0dc427743f8..ac7c6020c443 100644 --- a/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/intel_dsi_dcs_backlight.c @@ -159,7 +159,7 @@ static int dcs_setup_backlight(struct intel_connector *connector, int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector) { struct drm_device *dev = intel_connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *encoder = intel_connector->encoder; struct intel_panel *panel = &intel_connector->panel; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 4a3da875b620..cd154ce6b6c1 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -303,7 +303,7 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv, static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) { struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u8 gpio_source, gpio_index; bool value; @@ -469,7 +469,7 @@ static int vbt_panel_get_modes(struct drm_panel *panel) struct vbt_panel *vbt_panel = to_vbt_panel(panel); struct intel_dsi *intel_dsi = vbt_panel->intel_dsi; struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_display_mode *mode; if (!panel->connector) @@ -497,7 +497,7 @@ static const struct drm_panel_funcs vbt_panel_funcs = { struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id) { struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct mipi_config *mipi_config = dev_priv->vbt.dsi.config; struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps; struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode; diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 1fcddeb3303d..6ab58a01b18e 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -114,7 +114,7 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv, static int vlv_compute_dsi_pll(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int ret; u32 dsi_clk; @@ -325,7 +325,7 @@ static u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp, u32 dsi_clk; u32 dsi_ratio; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); /* Divide by zero */ if (!pipe_bpp) { @@ -360,7 +360,7 @@ u32 intel_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp, static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) { u32 temp; - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); temp = I915_READ(MIPI_CTRL(port)); @@ -374,7 +374,7 @@ static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port, const struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 tmp; u32 dsi_rate = 0; u32 pll_ratio = 0; @@ -469,7 +469,7 @@ static int bxt_compute_dsi_pll(struct intel_encoder *encoder, static void bxt_enable_dsi_pll(struct intel_encoder *encoder, const struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); enum port port; u32 val; @@ -550,7 +550,7 @@ static void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) { u32 tmp; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* Clear old configurations */ tmp = I915_READ(BXT_MIPI_CLOCK_CTL); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 14b1d3f333a4..47bdf9dad0d3 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -122,7 +122,7 @@ static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector) static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dvo *intel_dvo = intel_attached_dvo(&connector->base); u32 tmp; @@ -138,7 +138,7 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dvo *intel_dvo = enc_to_dvo(encoder); u32 tmp; @@ -155,7 +155,7 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, static void intel_dvo_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dvo *intel_dvo = enc_to_dvo(encoder); u32 tmp, flags = 0; @@ -176,7 +176,7 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, static void intel_disable_dvo(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dvo *intel_dvo = enc_to_dvo(encoder); i915_reg_t dvo_reg = intel_dvo->dev.dvo_reg; u32 temp = I915_READ(dvo_reg); @@ -188,7 +188,7 @@ static void intel_disable_dvo(struct intel_encoder *encoder) static void intel_enable_dvo(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dvo *intel_dvo = enc_to_dvo(encoder); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); i915_reg_t dvo_reg = intel_dvo->dev.dvo_reg; @@ -256,7 +256,7 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder, static void intel_dvo_pre_enable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; struct intel_dvo *intel_dvo = enc_to_dvo(encoder); @@ -305,7 +305,7 @@ intel_dvo_detect(struct drm_connector *connector, bool force) static int intel_dvo_get_modes(struct drm_connector *connector) { - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); const struct drm_display_mode *fixed_mode = to_intel_connector(connector)->panel.fixed_mode; @@ -379,7 +379,7 @@ static struct drm_display_mode * intel_dvo_get_current_mode(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dvo *intel_dvo = intel_attached_dvo(connector); uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); struct drm_display_mode *mode = NULL; @@ -421,7 +421,7 @@ static char intel_dvo_port_name(i915_reg_t dvo_reg) void intel_dvo_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *intel_encoder; struct intel_dvo *intel_dvo; struct intel_connector *intel_connector; diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 978d79532f96..067b6f518e48 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -445,7 +445,7 @@ out: static void intel_fbc_schedule_activation(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_work *work = &fbc->work; @@ -555,7 +555,7 @@ again: static int intel_fbc_alloc_cfb(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; struct drm_mm_node *uninitialized_var(compressed_llb); int size, fb_cpp, ret; @@ -686,7 +686,7 @@ static bool pixel_format_is_valid(struct drm_i915_private *dev_priv, */ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; unsigned int effective_w, effective_h, max_w, max_h; @@ -713,7 +713,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; struct drm_framebuffer *fb = plane_state->base.fb; @@ -746,7 +746,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, static bool intel_fbc_can_activate(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; @@ -818,7 +818,7 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc) static bool intel_fbc_can_choose(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; if (intel_vgpu_active(dev_priv)) { @@ -847,7 +847,7 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc) static void intel_fbc_get_reg_params(struct intel_crtc *crtc, struct intel_fbc_reg_params *params) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_state_cache *cache = &fbc->state_cache; @@ -880,7 +880,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) @@ -906,7 +906,7 @@ unlock: static void __intel_fbc_post_update(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_reg_params old_params; @@ -939,7 +939,7 @@ static void __intel_fbc_post_update(struct intel_crtc *crtc) void intel_fbc_post_update(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) @@ -1085,7 +1085,7 @@ void intel_fbc_enable(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) @@ -1156,7 +1156,7 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv) */ void intel_fbc_disable(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_fbc *fbc = &dev_priv->fbc; if (!fbc_supported(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 224180e402be..5205afd69ff6 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -703,7 +703,7 @@ static void intel_fbdev_suspend_worker(struct work_struct *work) int intel_fbdev_init(struct drm_device *dev) { struct intel_fbdev *ifbdev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int ret; if (WARN_ON(INTEL_INFO(dev)->num_pipes == 0)) @@ -762,7 +762,7 @@ static void intel_fbdev_sync(struct intel_fbdev *ifbdev) void intel_fbdev_fini(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_fbdev *ifbdev = dev_priv->fbdev; if (!ifbdev) @@ -778,7 +778,7 @@ void intel_fbdev_fini(struct drm_device *dev) void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_fbdev *ifbdev = dev_priv->fbdev; struct fb_info *info; @@ -827,7 +827,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous void intel_fbdev_output_poll_changed(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (dev_priv->fbdev) drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); } @@ -835,7 +835,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev) void intel_fbdev_restore_mode(struct drm_device *dev) { int ret; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_fbdev *ifbdev = dev_priv->fbdev; struct drm_fb_helper *fb_helper; diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 9be839a242f9..3fca95501890 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -50,7 +50,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc; enum pipe pipe; @@ -68,7 +68,7 @@ static bool ivb_can_enable_err_int(struct drm_device *dev) static bool cpt_can_enable_serr_int(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe; struct intel_crtc *crtc; @@ -105,7 +105,7 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable, bool old) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t reg = PIPESTAT(pipe); u32 pipestat = I915_READ(reg) & 0xffff0000; @@ -123,7 +123,7 @@ static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN : DE_PIPEB_FIFO_UNDERRUN; @@ -154,7 +154,7 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable, bool old) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (enable) { I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); @@ -176,7 +176,7 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (enable) bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN); @@ -188,7 +188,7 @@ static void ibx_set_fifo_underrun_reporting(struct drm_device *dev, enum transcoder pch_transcoder, bool enable) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t bit = (pch_transcoder == TRANSCODER_A) ? SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER; @@ -220,7 +220,7 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, enum transcoder pch_transcoder, bool enable, bool old) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (enable) { I915_WRITE(SERR_INT, @@ -244,7 +244,7 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); bool old; diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index d80b617ad9af..7d8cc3e90b34 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -413,7 +413,7 @@ static int i915_reset_guc(struct drm_i915_private *dev_priv) */ int intel_guc_setup(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; const char *fw_path = guc_fw->guc_fw_path; int retries, ret, err; @@ -681,7 +681,7 @@ fail: */ void intel_guc_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; const char *fw_path; @@ -734,7 +734,7 @@ void intel_guc_init(struct drm_device *dev) */ void intel_guc_fini(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 86e1fdb70141..4f4e4b535683 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -47,7 +47,7 @@ static void assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) { struct drm_device *dev = intel_hdmi_to_dev(intel_hdmi); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t enabled_bits; enabled_bits = HAS_DDI(dev) ? DDI_BUF_CTL_ENABLE : SDVO_ENABLE; @@ -138,7 +138,7 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, { const uint32_t *data = frame; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 val = I915_READ(VIDEO_DIP_CTL); int i; @@ -192,7 +192,7 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, { const uint32_t *data = frame; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe); u32 val = I915_READ(reg); @@ -251,7 +251,7 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, { const uint32_t *data = frame; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe); u32 val = I915_READ(reg); @@ -308,7 +308,7 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, { const uint32_t *data = frame; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); u32 val = I915_READ(reg); @@ -366,7 +366,7 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, { const uint32_t *data = frame; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder); @@ -508,7 +508,7 @@ static void g4x_set_infoframes(struct drm_encoder *encoder, bool enable, const struct drm_display_mode *adjusted_mode) { - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->dev); struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; i915_reg_t reg = VIDEO_DIP_CTL; @@ -629,7 +629,7 @@ static bool gcp_default_phase_possible(int pipe_bpp, static bool intel_hdmi_set_gcp_infoframe(struct drm_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->dev); struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); i915_reg_t reg; u32 val = 0; @@ -661,7 +661,7 @@ static void ibx_set_infoframes(struct drm_encoder *encoder, bool enable, const struct drm_display_mode *adjusted_mode) { - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; @@ -713,7 +713,7 @@ static void cpt_set_infoframes(struct drm_encoder *encoder, bool enable, const struct drm_display_mode *adjusted_mode) { - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe); @@ -755,7 +755,7 @@ static void vlv_set_infoframes(struct drm_encoder *encoder, bool enable, const struct drm_display_mode *adjusted_mode) { - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->dev); struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); @@ -807,7 +807,7 @@ static void hsw_set_infoframes(struct drm_encoder *encoder, bool enable, const struct drm_display_mode *adjusted_mode) { - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); i915_reg_t reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config->cpu_transcoder); @@ -855,7 +855,7 @@ void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) static void intel_hdmi_prepare(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; @@ -894,7 +894,7 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); enum intel_display_power_domain power_domain; u32 tmp; @@ -931,7 +931,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, { struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 tmp, flags = 0; int dotclock; @@ -988,7 +988,7 @@ static void intel_enable_hdmi_audio(struct intel_encoder *encoder) static void g4x_enable_hdmi(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); u32 temp; @@ -1009,7 +1009,7 @@ static void g4x_enable_hdmi(struct intel_encoder *encoder) static void ibx_enable_hdmi(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); u32 temp; @@ -1058,7 +1058,7 @@ static void ibx_enable_hdmi(struct intel_encoder *encoder) static void cpt_enable_hdmi(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); enum pipe pipe = crtc->pipe; @@ -1115,7 +1115,7 @@ static void vlv_enable_hdmi(struct intel_encoder *encoder) static void intel_disable_hdmi(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); u32 temp; @@ -1575,7 +1575,7 @@ intel_hdmi_set_property(struct drm_connector *connector, struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_digital_port *intel_dig_port = hdmi_to_dig_port(intel_hdmi); - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); int ret; ret = drm_object_property_set_value(&connector->base, property, val); @@ -1674,7 +1674,7 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder) struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); struct intel_hdmi *intel_hdmi = &dport->hdmi; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; @@ -1722,7 +1722,7 @@ static void vlv_hdmi_post_disable(struct intel_encoder *encoder) static void chv_hdmi_post_disable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); mutex_lock(&dev_priv->sb_lock); @@ -1737,7 +1737,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); struct intel_hdmi *intel_hdmi = &dport->hdmi; struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; @@ -1807,7 +1807,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi; struct intel_encoder *intel_encoder = &intel_dig_port->base; struct drm_device *dev = intel_encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_dig_port->port; uint8_t alternate_ddc_pin; diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 6bc4c064df0b..3c6f338866da 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -113,7 +113,7 @@ to_intel_gmbus(struct i2c_adapter *i2c) void intel_i2c_reset(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(GMBUS0, 0); I915_WRITE(GMBUS4, 0); @@ -632,7 +632,7 @@ static const struct i2c_algorithm gmbus_algorithm = { */ int intel_setup_gmbus(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_gmbus *bus; unsigned int pin; int ret; @@ -736,7 +736,7 @@ void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) void intel_teardown_gmbus(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_gmbus *bus; unsigned int pin; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2e66f310595f..676b53200e94 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -823,7 +823,7 @@ int intel_execlists_submission(struct i915_execbuffer_params *params, { struct drm_device *dev = params->dev; struct intel_engine_cs *engine = params->engine; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_ringbuffer *ringbuf = params->ctx->engine[engine->id].ringbuf; u64 exec_start; int instp_mode; @@ -2172,7 +2172,7 @@ logical_ring_setup(struct drm_i915_private *dev_priv, enum intel_engine_id id) */ int intel_logical_rings_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); unsigned int mask = 0; unsigned int i; int ret; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 681c6fd72ff6..49550470483e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -72,7 +72,7 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); enum intel_display_power_domain power_domain; u32 tmp; @@ -106,7 +106,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); u32 tmp, flags = 0; @@ -140,7 +140,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder) { struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; int pipe = crtc->pipe; @@ -216,7 +216,7 @@ static void intel_enable_lvds(struct intel_encoder *encoder) struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); struct intel_connector *intel_connector = &lvds_encoder->attached_connector->base; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t ctl_reg, stat_reg; if (HAS_PCH_SPLIT(dev)) { @@ -241,7 +241,7 @@ static void intel_disable_lvds(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); i915_reg_t ctl_reg, stat_reg; if (HAS_PCH_SPLIT(dev)) { @@ -442,7 +442,7 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, container_of(nb, struct intel_lvds_connector, lid_notifier); struct drm_connector *connector = &lvds_connector->base.base; struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (dev->switch_power_state != DRM_SWITCH_POWER_ON) return NOTIFY_OK; @@ -833,7 +833,7 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) { struct drm_device *dev = lvds_encoder->base.base.dev; unsigned int val; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* use the module option value if specified */ if (i915.lvds_channel_mode > 0) @@ -883,7 +883,7 @@ static bool intel_lvds_supported(struct drm_device *dev) */ void intel_lvds_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_lvds_encoder *lvds_encoder; struct intel_encoder *intel_encoder; struct intel_lvds_connector *lvds_connector; diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 38a4c8ce7e63..f2584d0a01ab 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -82,7 +82,7 @@ void intel_attach_force_audio_property(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_property *prop; prop = dev_priv->force_audio_property; @@ -109,7 +109,7 @@ void intel_attach_broadcast_rgb_property(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_property *prop; prop = dev_priv->broadcast_rgb_property; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index eb93f90bb74d..e9887d9321a3 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1084,7 +1084,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_intel_overlay_put_image *put_image_rec = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_overlay *overlay; struct drm_crtc *drmmode_crtc; struct intel_crtc *crtc; @@ -1282,7 +1282,7 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_intel_overlay_attrs *attrs = data; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_overlay *overlay; struct overlay_registers __iomem *regs; int ret; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 3c0b97f0bfae..a8b473350597 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -377,7 +377,7 @@ out: enum drm_connector_status intel_panel_detect(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* Assume that the BIOS does not lie through the OpRegion... */ if (!i915.panel_ignore_lid && dev_priv->opregion.lid_state) { @@ -1142,7 +1142,7 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 hw_level; int ret; @@ -1316,7 +1316,7 @@ static u32 i9xx_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) static u32 i965_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { struct drm_device *dev = connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int clock; if (IS_G4X(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 814b0dfaf640..0560b7c90244 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -57,7 +57,7 @@ static void gen9_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl */ I915_WRITE(CHICKEN_PAR1_1, @@ -83,7 +83,7 @@ static void gen9_init_clock_gating(struct drm_device *dev) static void bxt_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); gen9_init_clock_gating(dev); @@ -109,7 +109,7 @@ static void bxt_init_clock_gating(struct drm_device *dev) static void i915_pineview_get_mem_freq(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 tmp; tmp = I915_READ(CLKCFG); @@ -148,7 +148,7 @@ static void i915_pineview_get_mem_freq(struct drm_device *dev) static void i915_ironlake_get_mem_freq(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u16 ddrpll, csipll; ddrpll = I915_READ16(DDRMPLL1); @@ -375,7 +375,7 @@ static const int pessimal_latency_ns = 5000; static int vlv_get_fifo_size(struct drm_device *dev, enum pipe pipe, int plane) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int sprite0_start, sprite1_start, size; switch (pipe) { @@ -426,7 +426,7 @@ static int vlv_get_fifo_size(struct drm_device *dev, static int i9xx_get_fifo_size(struct drm_device *dev, int plane) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t dsparb = I915_READ(DSPARB); int size; @@ -442,7 +442,7 @@ static int i9xx_get_fifo_size(struct drm_device *dev, int plane) static int i830_get_fifo_size(struct drm_device *dev, int plane) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t dsparb = I915_READ(DSPARB); int size; @@ -459,7 +459,7 @@ static int i830_get_fifo_size(struct drm_device *dev, int plane) static int i845_get_fifo_size(struct drm_device *dev, int plane) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t dsparb = I915_READ(DSPARB); int size; @@ -637,7 +637,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev) static void pineview_update_wm(struct drm_crtc *unused_crtc) { struct drm_device *dev = unused_crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; const struct cxsr_latency *latency; u32 reg; @@ -934,7 +934,7 @@ static unsigned int vlv_wm_method2(unsigned int pixel_rate, static void vlv_setup_wm_latency(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* all latencies in usec */ dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; @@ -1325,7 +1325,7 @@ static void vlv_merge_wm(struct drm_device *dev, static void vlv_update_wm(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; struct vlv_wm_values wm = {}; @@ -1381,7 +1381,7 @@ static void g4x_update_wm(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; static const int sr_latency_ns = 12000; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int planea_wm, planeb_wm, cursora_wm, cursorb_wm; int plane_sr, cursor_sr; unsigned int enabled = 0; @@ -1438,7 +1438,7 @@ static void g4x_update_wm(struct drm_crtc *crtc) static void i965_update_wm(struct drm_crtc *unused_crtc) { struct drm_device *dev = unused_crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; int srwm = 1; int cursor_sr = 16; @@ -1512,7 +1512,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) static void i9xx_update_wm(struct drm_crtc *unused_crtc) { struct drm_device *dev = unused_crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); const struct intel_watermark_params *wm_info; uint32_t fwater_lo; uint32_t fwater_hi; @@ -1642,7 +1642,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) static void i845_update_wm(struct drm_crtc *unused_crtc) { struct drm_device *dev = unused_crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; const struct drm_display_mode *adjusted_mode; uint32_t fwater_lo; @@ -2070,7 +2070,7 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *cstate) static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8]) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (IS_GEN9(dev)) { uint32_t val; @@ -2250,7 +2250,7 @@ static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, static void snb_wm_latency_quirk(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); bool changed; /* @@ -2272,7 +2272,7 @@ static void snb_wm_latency_quirk(struct drm_device *dev) static void ilk_setup_wm_latency(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); intel_read_wm_latency(dev, dev_priv->wm.pri_latency); @@ -2294,7 +2294,7 @@ static void ilk_setup_wm_latency(struct drm_device *dev) static void skl_setup_wm_latency(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); intel_read_wm_latency(dev, dev_priv->wm.skl_latency); intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); @@ -2330,7 +2330,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); struct intel_pipe_wm *pipe_wm; struct drm_device *dev = state->dev; - const struct drm_i915_private *dev_priv = dev->dev_private; + const struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane; struct intel_plane_state *pristate = NULL; struct intel_plane_state *sprstate = NULL; @@ -2505,7 +2505,7 @@ static void ilk_wm_merge(struct drm_device *dev, const struct ilk_wm_maximums *max, struct intel_pipe_wm *merged) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int level, max_level = ilk_wm_max_level(dev); int last_enabled_level = max_level; @@ -2565,7 +2565,7 @@ static int ilk_wm_lp_to_level(int wm_lp, const struct intel_pipe_wm *pipe_wm) /* The value we need to program into the WM_LPx latency field */ static unsigned int ilk_wm_lp_latency(struct drm_device *dev, int level) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (IS_HASWELL(dev) || IS_BROADWELL(dev)) return 2 * level; @@ -2840,7 +2840,7 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv, bool ilk_disable_lp_wm(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); } @@ -3595,7 +3595,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate, struct skl_pipe_wm *pipe_wm) { struct drm_device *dev = cstate->base.crtc->dev; - const struct drm_i915_private *dev_priv = dev->dev_private; + const struct drm_i915_private *dev_priv = to_i915(dev); int level, max_level = ilk_wm_max_level(dev); int ret; @@ -4015,7 +4015,7 @@ static void skl_update_wm(struct drm_crtc *crtc) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct skl_wm_values *results = &dev_priv->wm.skl_results; struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal; @@ -4158,7 +4158,7 @@ static void skl_pipe_wm_active_state(uint32_t val, static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct skl_wm_values *hw = &dev_priv->wm.skl_hw; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); @@ -4212,7 +4212,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) void skl_wm_get_hw_state(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb; struct drm_crtc *crtc; @@ -4232,7 +4232,7 @@ void skl_wm_get_hw_state(struct drm_device *dev) static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct ilk_wm_values *hw = &dev_priv->wm.hw; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); @@ -4436,7 +4436,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev) void ilk_wm_get_hw_state(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct ilk_wm_values *hw = &dev_priv->wm.hw; struct drm_crtc *crtc; @@ -4498,7 +4498,7 @@ void ilk_wm_get_hw_state(struct drm_device *dev) */ void intel_update_watermarks(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); if (dev_priv->display.update_wm) dev_priv->display.update_wm(crtc); @@ -6713,7 +6713,7 @@ void intel_reset_gt_powersave(struct drm_i915_private *dev_priv) static void ibx_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* * On Ibex Peak and Cougar Point, we need to disable clock @@ -6725,7 +6725,7 @@ static void ibx_init_clock_gating(struct drm_device *dev) static void g4x_disable_trickle_feed(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe; for_each_pipe(dev_priv, pipe) { @@ -6740,7 +6740,7 @@ static void g4x_disable_trickle_feed(struct drm_device *dev) static void ilk_init_lp_watermarks(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(WM3_LP_ILK, I915_READ(WM3_LP_ILK) & ~WM1_LP_SR_EN); I915_WRITE(WM2_LP_ILK, I915_READ(WM2_LP_ILK) & ~WM1_LP_SR_EN); @@ -6754,7 +6754,7 @@ static void ilk_init_lp_watermarks(struct drm_device *dev) static void ironlake_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; /* @@ -6828,7 +6828,7 @@ static void ironlake_init_clock_gating(struct drm_device *dev) static void cpt_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); int pipe; uint32_t val; @@ -6865,7 +6865,7 @@ static void cpt_init_clock_gating(struct drm_device *dev) static void gen6_check_mch_setup(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t tmp; tmp = I915_READ(MCH_SSKPD); @@ -6876,7 +6876,7 @@ static void gen6_check_mch_setup(struct drm_device *dev) static void gen6_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; I915_WRITE(ILK_DSPCLK_GATE_D, dspclk_gate); @@ -6991,7 +6991,7 @@ static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv) static void lpt_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* * TODO: this bit should only be enabled when really needed, then @@ -7010,7 +7010,7 @@ static void lpt_init_clock_gating(struct drm_device *dev) static void lpt_suspend_hw(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (HAS_PCH_LPT_LP(dev)) { uint32_t val = I915_READ(SOUTH_DSPCLK_GATE_D); @@ -7045,7 +7045,7 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, static void kabylake_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); gen9_init_clock_gating(dev); @@ -7066,7 +7066,7 @@ static void kabylake_init_clock_gating(struct drm_device *dev) static void skylake_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); gen9_init_clock_gating(dev); @@ -7081,7 +7081,7 @@ static void skylake_init_clock_gating(struct drm_device *dev) static void broadwell_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe; ilk_init_lp_watermarks(dev); @@ -7132,7 +7132,7 @@ static void broadwell_init_clock_gating(struct drm_device *dev) static void haswell_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); ilk_init_lp_watermarks(dev); @@ -7188,7 +7188,7 @@ static void haswell_init_clock_gating(struct drm_device *dev) static void ivybridge_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t snpcr; ilk_init_lp_watermarks(dev); @@ -7286,7 +7286,7 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) static void valleyview_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* WaDisableEarlyCull:vlv */ I915_WRITE(_3D_CHICKEN3, @@ -7368,7 +7368,7 @@ static void valleyview_init_clock_gating(struct drm_device *dev) static void cherryview_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* WaVSRefCountFullforceMissDisable:chv */ /* WaDSRefCountFullforceMissDisable:chv */ @@ -7404,7 +7404,7 @@ static void cherryview_init_clock_gating(struct drm_device *dev) static void g4x_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t dspclk_gate; I915_WRITE(RENCLK_GATE_D1, 0); @@ -7431,7 +7431,7 @@ static void g4x_init_clock_gating(struct drm_device *dev) static void crestline_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); I915_WRITE(RENCLK_GATE_D2, 0); @@ -7447,7 +7447,7 @@ static void crestline_init_clock_gating(struct drm_device *dev) static void broadwater_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | I965_RCC_CLOCK_GATE_DISABLE | @@ -7464,7 +7464,7 @@ static void broadwater_init_clock_gating(struct drm_device *dev) static void gen3_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 dstate = I915_READ(D_STATE); dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | @@ -7489,7 +7489,7 @@ static void gen3_init_clock_gating(struct drm_device *dev) static void i85x_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); @@ -7503,7 +7503,7 @@ static void i85x_init_clock_gating(struct drm_device *dev) static void i830_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); @@ -7514,7 +7514,7 @@ static void i830_init_clock_gating(struct drm_device *dev) void intel_init_clock_gating(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->display.init_clock_gating(dev); } @@ -7582,7 +7582,7 @@ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) /* Set up chip specific power management-related functions */ void intel_init_pm(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); intel_fbc_init(dev_priv); @@ -7812,7 +7812,7 @@ void intel_queue_rps_boost_for_request(struct drm_i915_gem_request *req) void intel_pm_setup(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); mutex_init(&dev_priv->rps.hw_lock); spin_lock_init(&dev_priv->rps.client_lock); diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 8d25c45aa6fe..68bd0bb34817 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -63,7 +63,7 @@ static bool is_edp_psr(struct intel_dp *intel_dp) static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t val; val = I915_READ(VLV_PSRSTAT(pipe)) & @@ -77,7 +77,7 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp, { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder); @@ -107,7 +107,7 @@ static void vlv_psr_setup_vsc(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc = intel_dig_port->base.base.crtc; enum pipe pipe = to_intel_crtc(crtc)->pipe; uint32_t val; @@ -173,7 +173,7 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t aux_clock_divider; i915_reg_t aux_ctl_reg; static const uint8_t aux_msg[] = { @@ -220,7 +220,7 @@ static void vlv_psr_enable_source(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc = dig_port->base.base.crtc; enum pipe pipe = to_intel_crtc(crtc)->pipe; @@ -235,7 +235,7 @@ static void vlv_psr_activate(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc = dig_port->base.base.crtc; enum pipe pipe = to_intel_crtc(crtc)->pipe; @@ -252,7 +252,7 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); uint32_t max_sleep_time = 0x1f; /* Lately it was identified that depending on panel idle frame count @@ -324,7 +324,7 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc = dig_port->base.base.crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -378,7 +378,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE); WARN_ON(dev_priv->psr.active); @@ -407,7 +407,7 @@ void intel_psr_enable(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc); if (!HAS_PSR(dev)) { @@ -494,7 +494,7 @@ static void vlv_psr_disable(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(intel_dig_port->base.base.crtc); uint32_t val; @@ -524,7 +524,7 @@ static void hsw_psr_disable(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (dev_priv->psr.active) { I915_WRITE(EDP_PSR_CTL, @@ -554,7 +554,7 @@ void intel_psr_disable(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); mutex_lock(&dev_priv->psr.lock); if (!dev_priv->psr.enabled) { @@ -630,7 +630,7 @@ unlock: static void intel_psr_exit(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dp *intel_dp = dev_priv->psr.enabled; struct drm_crtc *crtc = dp_to_dig_port(intel_dp)->base.base.crtc; enum pipe pipe = to_intel_crtc(crtc)->pipe; @@ -685,7 +685,7 @@ static void intel_psr_exit(struct drm_device *dev) void intel_psr_single_frame_update(struct drm_device *dev, unsigned frontbuffer_bits) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; enum pipe pipe; u32 val; @@ -733,7 +733,7 @@ void intel_psr_single_frame_update(struct drm_device *dev, void intel_psr_invalidate(struct drm_device *dev, unsigned frontbuffer_bits) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; enum pipe pipe; @@ -771,7 +771,7 @@ void intel_psr_invalidate(struct drm_device *dev, void intel_psr_flush(struct drm_device *dev, unsigned frontbuffer_bits, enum fb_op_origin origin) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc *crtc; enum pipe pipe; @@ -807,7 +807,7 @@ void intel_psr_flush(struct drm_device *dev, */ void intel_psr_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ? HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 3fafc35d99c1..428ed62dc5de 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2837,7 +2837,7 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv, int intel_init_render_ring_buffer(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine = &dev_priv->engine[RCS]; int ret; @@ -2899,7 +2899,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) int intel_init_bsd_ring_buffer(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine = &dev_priv->engine[VCS]; engine->name = "bsd ring"; @@ -2937,7 +2937,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) */ int intel_init_bsd2_ring_buffer(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine = &dev_priv->engine[VCS2]; engine->name = "bsd2 ring"; @@ -2957,7 +2957,7 @@ int intel_init_bsd2_ring_buffer(struct drm_device *dev) int intel_init_blt_ring_buffer(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine = &dev_priv->engine[BCS]; engine->name = "blitter ring"; @@ -2980,7 +2980,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) int intel_init_vebox_ring_buffer(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_engine_cs *engine = &dev_priv->engine[VECS]; engine->name = "video enhancement ring"; diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index ba28f5141687..321121e8fa2c 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -240,7 +240,7 @@ intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) { struct drm_device *dev = intel_sdvo->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 bval = val, cval = val; int i; @@ -1195,7 +1195,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder, static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder) { struct drm_device *dev = intel_encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *crtc = to_intel_crtc(intel_encoder->base.crtc); const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; struct drm_display_mode *mode = &crtc->config->base.mode; @@ -1330,7 +1330,7 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); u16 active_outputs = 0; u32 tmp; @@ -1353,7 +1353,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_sdvo_dtd dtd; int encoder_pixel_multiplier = 0; @@ -1436,7 +1436,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, static void intel_disable_sdvo(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); u32 temp; @@ -1489,7 +1489,7 @@ static void pch_post_disable_sdvo(struct intel_encoder *encoder) static void intel_enable_sdvo(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); u32 temp; @@ -1633,7 +1633,7 @@ intel_sdvo_get_edid(struct drm_connector *connector) static struct edid * intel_sdvo_get_analog_edid(struct drm_connector *connector) { - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); return drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, @@ -1916,7 +1916,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) { struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); struct drm_display_mode *newmode; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", @@ -2001,7 +2001,7 @@ intel_sdvo_set_property(struct drm_connector *connector, { struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(connector->dev); uint16_t temp_value; uint8_t cmd; int ret; @@ -2338,7 +2338,7 @@ intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device) static u8 intel_sdvo_get_slave_addr(struct drm_device *dev, struct intel_sdvo *sdvo) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct sdvo_device_mapping *my_mapping, *other_mapping; if (sdvo->port == PORT_B) { @@ -2952,7 +2952,7 @@ static void assert_sdvo_port_valid(const struct drm_i915_private *dev_priv, bool intel_sdvo_init(struct drm_device *dev, i915_reg_t sdvo_reg, enum port port) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *intel_encoder; struct intel_sdvo *intel_sdvo; int i; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index fc654173c491..0de935ad01c2 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -199,7 +199,7 @@ skl_update_plane(struct drm_plane *drm_plane, const struct intel_plane_state *plane_state) { struct drm_device *dev = drm_plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane = to_intel_plane(drm_plane); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); @@ -303,7 +303,7 @@ static void skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) { struct drm_device *dev = dplane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane = to_intel_plane(dplane); const int pipe = intel_plane->pipe; const int plane = intel_plane->plane + 1; @@ -317,7 +317,7 @@ skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) static void chv_update_csc(struct intel_plane *intel_plane, uint32_t format) { - struct drm_i915_private *dev_priv = intel_plane->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev); int plane = intel_plane->plane; /* Seems RGB data bypasses the CSC always */ @@ -359,7 +359,7 @@ vlv_update_plane(struct drm_plane *dplane, const struct intel_plane_state *plane_state) { struct drm_device *dev = dplane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane = to_intel_plane(dplane); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); @@ -485,7 +485,7 @@ static void vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) { struct drm_device *dev = dplane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane = to_intel_plane(dplane); int pipe = intel_plane->pipe; int plane = intel_plane->plane; @@ -502,7 +502,7 @@ ivb_update_plane(struct drm_plane *plane, const struct intel_plane_state *plane_state) { struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane = to_intel_plane(plane); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); @@ -624,7 +624,7 @@ static void ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) { struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane = to_intel_plane(plane); int pipe = intel_plane->pipe; @@ -643,7 +643,7 @@ ilk_update_plane(struct drm_plane *plane, const struct intel_plane_state *plane_state) { struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane = to_intel_plane(plane); struct drm_framebuffer *fb = plane_state->base.fb; struct drm_i915_gem_object *obj = intel_fb_obj(fb); @@ -753,7 +753,7 @@ static void ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) { struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_plane *intel_plane = to_intel_plane(plane); int pipe = intel_plane->pipe; diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 153190475ebd..49136ad5473e 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -826,7 +826,7 @@ static bool intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 tmp = I915_READ(TV_CTL); if (!(tmp & TV_ENC_ENABLE)) @@ -841,7 +841,7 @@ static void intel_enable_tv(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); /* Prevents vblank waits from timing out in intel_tv_detect_type() */ intel_wait_for_vblank(encoder->base.dev, @@ -854,7 +854,7 @@ static void intel_disable_tv(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE); } @@ -1013,7 +1013,7 @@ static void set_color_conversion(struct drm_i915_private *dev_priv, static void intel_tv_pre_enable(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_tv *intel_tv = enc_to_tv(encoder); const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); @@ -1173,7 +1173,7 @@ intel_tv_detect_type(struct intel_tv *intel_tv, struct drm_crtc *crtc = connector->state->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; int type; @@ -1523,7 +1523,7 @@ static const struct drm_encoder_funcs intel_tv_enc_funcs = { void intel_tv_init(struct drm_device *dev) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_connector *connector; struct intel_tv *intel_tv; struct intel_encoder *intel_encoder; diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 19d759ed7a30..1d65209c0998 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1409,7 +1409,7 @@ static const struct register_whitelist { int i915_reg_read_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_reg_read *reg = data; struct register_whitelist const *entry = whitelist; unsigned size; -- cgit v1.2.3 From f19ec8cb5a4e16299840be6220308793d443de3f Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Mon, 4 Jul 2016 11:34:37 +0100 Subject: drm/i915: convert a few more E->dev_private to to_i915(E) Also remove some redundant dev and dev_priv locals Signed-off-by: Dave Gordon Cc: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467626365-29871-1-git-send-email-david.s.gordon@intel.com Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467628477-25379-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- drivers/gpu/drm/i915/intel_display.c | 4 ---- drivers/gpu/drm/i915/intel_guc_loader.c | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7a88840b59fa..a7852dd0a3d4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4772,7 +4772,7 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, obj->fence_reg = I915_FENCE_REG_NONE; obj->madv = I915_MADV_WILLNEED; - i915_gem_info_add_obj(obj->base.dev->dev_private, obj->base.size); + i915_gem_info_add_obj(to_i915(obj->base.dev), obj->base.size); } static const struct drm_i915_gem_object_ops i915_gem_object_ops = { @@ -5398,7 +5398,7 @@ int i915_gem_open(struct drm_device *dev, struct drm_file *file) return -ENOMEM; file->driver_priv = file_priv; - file_priv->dev_priv = dev->dev_private; + file_priv->dev_priv = to_i915(dev); file_priv->file = file; INIT_LIST_HEAD(&file_priv->rps.link); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c3c620b4f589..4ff6e9304ef1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14144,15 +14144,11 @@ int skl_max_scale(struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state) { int max_scale; - struct drm_device *dev; - struct drm_i915_private *dev_priv; int crtc_clock, cdclk; if (!intel_crtc || !crtc_state->base.enable) return DRM_PLANE_HELPER_NO_SCALING; - dev = intel_crtc->base.dev; - dev_priv = dev->dev_private; crtc_clock = crtc_state->base.adjusted_mode.crtc_clock; cdclk = to_intel_atomic_state(crtc_state->base.state)->cdclk; diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 7d8cc3e90b34..d925e2daeb24 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -608,7 +608,7 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw) /* Header and uCode will be loaded to WOPCM. Size of the two. */ size = guc_fw->header_size + guc_fw->ucode_size; - if (size > guc_wopcm_size(dev->dev_private)) { + if (size > guc_wopcm_size(to_i915(dev))) { DRM_ERROR("Firmware is too large to fit in WOPCM\n"); goto fail; } -- cgit v1.2.3 From af1346a0f38fe5b762729a91ed10c7c7f59b76c9 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 4 Jul 2016 15:50:23 +0100 Subject: drm/i915: Explicitly convert some macros to boolean values Some IS_ and HAS_ macros can return any non-zero value for true. One potential problem with that is that someone could assign them to integers and be surprised with the result. Therefore it is probably safer to do the conversion to 0/1 in the macros themselves. Luckily this does not seem to have an effect on code size. Only one call site was getting bit by this and a patch for that has been sent as "drm/i915/guc: Protect against HAS_GUC_* returning true values other than one". v2: Added some extra braces as suggested by checkpatch. Signed-off-by: Tvrtko Ursulin Reviewed-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467643823-9798-1-git-send-email-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f0b1f43d0601..594ddbba3a64 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2763,14 +2763,14 @@ struct drm_i915_cmd_table { * have their own (e.g. HAS_PCH_SPLIT for ILK+ display, IS_foo for particular * chips, etc.). */ -#define IS_GEN2(dev) (INTEL_INFO(dev)->gen_mask & BIT(1)) -#define IS_GEN3(dev) (INTEL_INFO(dev)->gen_mask & BIT(2)) -#define IS_GEN4(dev) (INTEL_INFO(dev)->gen_mask & BIT(3)) -#define IS_GEN5(dev) (INTEL_INFO(dev)->gen_mask & BIT(4)) -#define IS_GEN6(dev) (INTEL_INFO(dev)->gen_mask & BIT(5)) -#define IS_GEN7(dev) (INTEL_INFO(dev)->gen_mask & BIT(6)) -#define IS_GEN8(dev) (INTEL_INFO(dev)->gen_mask & BIT(7)) -#define IS_GEN9(dev) (INTEL_INFO(dev)->gen_mask & BIT(8)) +#define IS_GEN2(dev) (!!(INTEL_INFO(dev)->gen_mask & BIT(1))) +#define IS_GEN3(dev) (!!(INTEL_INFO(dev)->gen_mask & BIT(2))) +#define IS_GEN4(dev) (!!(INTEL_INFO(dev)->gen_mask & BIT(3))) +#define IS_GEN5(dev) (!!(INTEL_INFO(dev)->gen_mask & BIT(4))) +#define IS_GEN6(dev) (!!(INTEL_INFO(dev)->gen_mask & BIT(5))) +#define IS_GEN7(dev) (!!(INTEL_INFO(dev)->gen_mask & BIT(6))) +#define IS_GEN8(dev) (!!(INTEL_INFO(dev)->gen_mask & BIT(7))) +#define IS_GEN9(dev) (!!(INTEL_INFO(dev)->gen_mask & BIT(8))) #define ENGINE_MASK(id) BIT(id) #define RENDER_RING ENGINE_MASK(RCS) @@ -2781,7 +2781,7 @@ struct drm_i915_cmd_table { #define ALL_ENGINES (~0) #define HAS_ENGINE(dev_priv, id) \ - (INTEL_INFO(dev_priv)->ring_mask & ENGINE_MASK(id)) + (!!(INTEL_INFO(dev_priv)->ring_mask & ENGINE_MASK(id))) #define HAS_BSD(dev_priv) HAS_ENGINE(dev_priv, VCS) #define HAS_BSD2(dev_priv) HAS_ENGINE(dev_priv, VCS2) @@ -2790,7 +2790,7 @@ struct drm_i915_cmd_table { #define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define HAS_SNOOP(dev) (INTEL_INFO(dev)->has_snoop) -#define HAS_EDRAM(dev) (__I915__(dev)->edram_cap & EDRAM_ENABLED) +#define HAS_EDRAM(dev) (!!(__I915__(dev)->edram_cap & EDRAM_ENABLED)) #define HAS_WT(dev) ((IS_HASWELL(dev) || IS_BROADWELL(dev)) && \ HAS_EDRAM(dev)) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) -- cgit v1.2.3 From b1379d49646e791def9a1c81ff7f04d571e71d7c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 Jul 2016 08:54:36 +0100 Subject: drm/i915: Replace lockless_dereference(bool) with READ_ONCE() After Joonas complained about using READ_ONCE() on the only use of the variable in the function, where the intent was to simply document that the read was intentionally racy and unlocked, I switched the READ_ONCE() over to lockless_dereference(). However, in linux-next that has a stronger type-check to only allow pointers and is no longer interchangeable with READ_ONCE(), see commit 331b6d8c7afc ("locking/barriers: Validate lockless_dereference() is used on a pointer type") Reported-by: Stephen Rothwell Fixes: 67d97da34917 ("drm/i915: Only start retire worker when idle") Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467705276-707-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_irq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a7852dd0a3d4..20123c09bc18 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3290,7 +3290,7 @@ i915_gem_retire_work_handler(struct work_struct *work) * We do not need to do this test under locking as in the worst-case * we queue the retire worker once too often. */ - if (lockless_dereference(dev_priv->gt.awake)) + if (READ_ONCE(dev_priv->gt.awake)) queue_delayed_work(dev_priv->wq, &dev_priv->gt.retire_work, round_jiffies_up_relative(HZ)); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f6de8dd567a2..2f01b0b959a1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3095,7 +3095,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) if (!i915.enable_hangcheck) return; - if (!lockless_dereference(dev_priv->gt.awake)) + if (!READ_ONCE(dev_priv->gt.awake)) return; /* As enabling the GPU requires fairly extensive mmio access, -- cgit v1.2.3 From 8eb95204d926ed0c3d1d588c352adef40ed673f2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:48:31 +0100 Subject: drm/i915: Amalgamate gen6_mm_switch() and vgpu_mm_switch() These are identical, so let's just use the same vfunc. Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467618513-4966-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_gem_gtt.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index cf6fdcb147c6..9d6ea275be89 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1683,17 +1683,6 @@ static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt, return 0; } -static int vgpu_mm_switch(struct i915_hw_ppgtt *ppgtt, - struct drm_i915_gem_request *req) -{ - struct intel_engine_cs *engine = req->engine; - struct drm_i915_private *dev_priv = to_i915(ppgtt->base.dev); - - I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G); - I915_WRITE(RING_PP_DIR_BASE(engine), get_pd_offset(ppgtt)); - return 0; -} - static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { @@ -1731,15 +1720,10 @@ static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt, struct drm_i915_gem_request *req) { struct intel_engine_cs *engine = req->engine; - struct drm_device *dev = ppgtt->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - + struct drm_i915_private *dev_priv = req->i915; I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G); I915_WRITE(RING_PP_DIR_BASE(engine), get_pd_offset(ppgtt)); - - POSTING_READ(RING_PP_DIR_DCLV(engine)); - return 0; } @@ -2074,18 +2058,15 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) int ret; ppgtt->base.pte_encode = ggtt->base.pte_encode; - if (IS_GEN6(dev)) { + if (intel_vgpu_active(dev_priv) || IS_GEN6(dev)) ppgtt->switch_mm = gen6_mm_switch; - } else if (IS_HASWELL(dev)) { + else if (IS_HASWELL(dev)) ppgtt->switch_mm = hsw_mm_switch; - } else if (IS_GEN7(dev)) { + else if (IS_GEN7(dev)) ppgtt->switch_mm = gen7_mm_switch; - } else + else BUG(); - if (intel_vgpu_active(dev_priv)) - ppgtt->switch_mm = vgpu_mm_switch; - ret = gen6_ppgtt_alloc(ppgtt); if (ret) return ret; -- cgit v1.2.3 From 2b2842887de75c340ab427b898aa867964316d2f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:48:32 +0100 Subject: drm/i915: Clean up GPU hang message Remove some redundant kernel messages as we deduce a hung GPU and capture the error state. v2: Fix "hang" vs "no progress" message whilst I was there v3: s/snprintf/scnprintf/ Signed-off-by: Chris Wilson Cc: Mika Kuoppala Link: http://patchwork.freedesktop.org/patch/msgid/1467618513-4966-2-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_irq.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2f01b0b959a1..3eadc8375449 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3084,9 +3084,8 @@ static void i915_hangcheck_elapsed(struct work_struct *work) container_of(work, typeof(*dev_priv), gpu_error.hangcheck_work.work); struct intel_engine_cs *engine; - enum intel_engine_id id; - int busy_count = 0, rings_hung = 0; - bool stuck[I915_NUM_ENGINES] = { 0 }; + unsigned int hung = 0, stuck = 0; + int busy_count = 0; #define BUSY 1 #define KICK 5 #define HUNG 20 @@ -3104,7 +3103,7 @@ static void i915_hangcheck_elapsed(struct work_struct *work) */ intel_uncore_arm_unclaimed_mmio_detection(dev_priv); - for_each_engine_id(engine, dev_priv, id) { + for_each_engine(engine, dev_priv) { bool busy = intel_engine_has_waiter(engine); u64 acthd; u32 seqno; @@ -3167,10 +3166,15 @@ static void i915_hangcheck_elapsed(struct work_struct *work) break; case HANGCHECK_HUNG: engine->hangcheck.score += HUNG; - stuck[id] = true; break; } } + + if (engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { + hung |= intel_engine_flag(engine); + if (engine->hangcheck.action != HANGCHECK_HUNG) + stuck |= intel_engine_flag(engine); + } } else { engine->hangcheck.action = HANGCHECK_ACTIVE; @@ -3195,17 +3199,24 @@ static void i915_hangcheck_elapsed(struct work_struct *work) busy_count += busy; } - for_each_engine_id(engine, dev_priv, id) { - if (engine->hangcheck.score >= HANGCHECK_SCORE_RING_HUNG) { - DRM_INFO("%s on %s\n", - stuck[id] ? "stuck" : "no progress", - engine->name); - rings_hung |= intel_engine_flag(engine); - } - } + if (hung) { + char msg[80]; + int len; - if (rings_hung) - i915_handle_error(dev_priv, rings_hung, "Engine(s) hung"); + /* If some rings hung but others were still busy, only + * blame the hanging rings in the synopsis. + */ + if (stuck != hung) + hung &= ~stuck; + len = scnprintf(msg, sizeof(msg), + "%s on ", stuck == hung ? "No progress" : "Hang"); + for_each_engine_masked(engine, dev_priv, hung) + len += scnprintf(msg + len, sizeof(msg) - len, + "%s, ", engine->name); + msg[len-2] = '\0'; + + return i915_handle_error(dev_priv, hung, msg); + } /* Reset timer in case GPU hangs without another request being added */ if (busy_count) -- cgit v1.2.3 From 9777cca0c4d3d35a97cb5711be575967712bd59b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 4 Jul 2016 08:48:33 +0100 Subject: drm/i915: Skip capturing an error state if we already have one As we only ever keep the first error state around, we can avoid some work that can be quite intrusive if we don't record the error the second time around. This does move the race whereby the user could discard one error state as the second is being captured, but that race exists in the current code and we hope that recapturing error state is only done for debugging. Note that as we discard the error state for simulated errors, igt that exercise error capture continue to function. Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467618513-4966-3-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_gpu_error.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 1d9aa3e6a334..4e8cacfc4e48 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1401,6 +1401,9 @@ void i915_capture_error_state(struct drm_i915_private *dev_priv, struct drm_i915_error_state *error; unsigned long flags; + if (READ_ONCE(dev_priv->gpu_error.first_error)) + return; + /* Account for pipe specific data like PIPE*STAT */ error = kzalloc(sizeof(*error), GFP_ATOMIC); if (!error) { -- cgit v1.2.3 From 94b4f3ba483ace6dd4a3f881e19cc18bdbafa6ef Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 Jul 2016 10:40:20 +0100 Subject: drm/i915: Split out runtime configuration of device info to its own file Let's reclaim a few hundred lines from i915_drv.c by splitting out the runtime configuration of the "constant" dev_priv->info. Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1467711623-2905-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.c | 413 ++----------------------------- drivers/gpu/drm/i915/i915_drv.h | 10 + drivers/gpu/drm/i915/intel_device_info.c | 388 +++++++++++++++++++++++++++++ 4 files changed, 421 insertions(+), 391 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_device_info.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 618293c8c9d9..684fc1cd08fa 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -14,6 +14,7 @@ i915-y := i915_drv.o \ i915_suspend.o \ i915_sysfs.o \ intel_csr.o \ + intel_device_info.o \ intel_pm.o \ intel_runtime_pm.o diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 695001ffd547..87295f6e5520 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -748,394 +748,6 @@ static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) } #endif -static void i915_dump_device_info(struct drm_i915_private *dev_priv) -{ - const struct intel_device_info *info = &dev_priv->info; - -#define PRINT_S(name) "%s" -#define SEP_EMPTY -#define PRINT_FLAG(name) info->name ? #name "," : "" -#define SEP_COMMA , - DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x rev=0x%02x flags=" - DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY), - info->gen, - dev_priv->dev->pdev->device, - dev_priv->dev->pdev->revision, - DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA)); -#undef PRINT_S -#undef SEP_EMPTY -#undef PRINT_FLAG -#undef SEP_COMMA -} - -static void cherryview_sseu_info_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_device_info *info; - u32 fuse, eu_dis; - - info = (struct intel_device_info *)&dev_priv->info; - fuse = I915_READ(CHV_FUSE_GT); - - info->slice_total = 1; - - if (!(fuse & CHV_FGT_DISABLE_SS0)) { - info->subslice_per_slice++; - eu_dis = fuse & (CHV_FGT_EU_DIS_SS0_R0_MASK | - CHV_FGT_EU_DIS_SS0_R1_MASK); - info->eu_total += 8 - hweight32(eu_dis); - } - - if (!(fuse & CHV_FGT_DISABLE_SS1)) { - info->subslice_per_slice++; - eu_dis = fuse & (CHV_FGT_EU_DIS_SS1_R0_MASK | - CHV_FGT_EU_DIS_SS1_R1_MASK); - info->eu_total += 8 - hweight32(eu_dis); - } - - info->subslice_total = info->subslice_per_slice; - /* - * CHV expected to always have a uniform distribution of EU - * across subslices. - */ - info->eu_per_subslice = info->subslice_total ? - info->eu_total / info->subslice_total : - 0; - /* - * CHV supports subslice power gating on devices with more than - * one subslice, and supports EU power gating on devices with - * more than one EU pair per subslice. - */ - info->has_slice_pg = 0; - info->has_subslice_pg = (info->subslice_total > 1); - info->has_eu_pg = (info->eu_per_subslice > 2); -} - -static void gen9_sseu_info_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_device_info *info; - int s_max = 3, ss_max = 4, eu_max = 8; - int s, ss; - u32 fuse2, s_enable, ss_disable, eu_disable; - u8 eu_mask = 0xff; - - info = (struct intel_device_info *)&dev_priv->info; - fuse2 = I915_READ(GEN8_FUSE2); - s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> - GEN8_F2_S_ENA_SHIFT; - ss_disable = (fuse2 & GEN9_F2_SS_DIS_MASK) >> - GEN9_F2_SS_DIS_SHIFT; - - info->slice_total = hweight32(s_enable); - /* - * The subslice disable field is global, i.e. it applies - * to each of the enabled slices. - */ - info->subslice_per_slice = ss_max - hweight32(ss_disable); - info->subslice_total = info->slice_total * - info->subslice_per_slice; - - /* - * Iterate through enabled slices and subslices to - * count the total enabled EU. - */ - for (s = 0; s < s_max; s++) { - if (!(s_enable & (0x1 << s))) - /* skip disabled slice */ - continue; - - eu_disable = I915_READ(GEN9_EU_DISABLE(s)); - for (ss = 0; ss < ss_max; ss++) { - int eu_per_ss; - - if (ss_disable & (0x1 << ss)) - /* skip disabled subslice */ - continue; - - eu_per_ss = eu_max - hweight8((eu_disable >> (ss*8)) & - eu_mask); - - /* - * Record which subslice(s) has(have) 7 EUs. we - * can tune the hash used to spread work among - * subslices if they are unbalanced. - */ - if (eu_per_ss == 7) - info->subslice_7eu[s] |= 1 << ss; - - info->eu_total += eu_per_ss; - } - } - - /* - * SKL is expected to always have a uniform distribution - * of EU across subslices with the exception that any one - * EU in any one subslice may be fused off for die - * recovery. BXT is expected to be perfectly uniform in EU - * distribution. - */ - info->eu_per_subslice = info->subslice_total ? - DIV_ROUND_UP(info->eu_total, - info->subslice_total) : 0; - /* - * SKL supports slice power gating on devices with more than - * one slice, and supports EU power gating on devices with - * more than one EU pair per subslice. BXT supports subslice - * power gating on devices with more than one subslice, and - * supports EU power gating on devices with more than one EU - * pair per subslice. - */ - info->has_slice_pg = ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && - (info->slice_total > 1)); - info->has_subslice_pg = (IS_BROXTON(dev) && (info->subslice_total > 1)); - info->has_eu_pg = (info->eu_per_subslice > 2); - - if (IS_BROXTON(dev)) { -#define IS_SS_DISABLED(_ss_disable, ss) (_ss_disable & (0x1 << ss)) - /* - * There is a HW issue in 2x6 fused down parts that requires - * Pooled EU to be enabled as a WA. The pool configuration - * changes depending upon which subslice is fused down. This - * doesn't affect if the device has all 3 subslices enabled. - */ - /* WaEnablePooledEuFor2x6:bxt */ - info->has_pooled_eu = ((info->subslice_per_slice == 3) || - (info->subslice_per_slice == 2 && - INTEL_REVID(dev) < BXT_REVID_C0)); - - info->min_eu_in_pool = 0; - if (info->has_pooled_eu) { - if (IS_SS_DISABLED(ss_disable, 0) || - IS_SS_DISABLED(ss_disable, 2)) - info->min_eu_in_pool = 3; - else if (IS_SS_DISABLED(ss_disable, 1)) - info->min_eu_in_pool = 6; - else - info->min_eu_in_pool = 9; - } -#undef IS_SS_DISABLED - } -} - -static void broadwell_sseu_info_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_device_info *info; - const int s_max = 3, ss_max = 3, eu_max = 8; - int s, ss; - u32 fuse2, eu_disable[s_max], s_enable, ss_disable; - - fuse2 = I915_READ(GEN8_FUSE2); - s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT; - ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT; - - eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK; - eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) | - ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) << - (32 - GEN8_EU_DIS0_S1_SHIFT)); - eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) | - ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) << - (32 - GEN8_EU_DIS1_S2_SHIFT)); - - - info = (struct intel_device_info *)&dev_priv->info; - info->slice_total = hweight32(s_enable); - - /* - * The subslice disable field is global, i.e. it applies - * to each of the enabled slices. - */ - info->subslice_per_slice = ss_max - hweight32(ss_disable); - info->subslice_total = info->slice_total * info->subslice_per_slice; - - /* - * Iterate through enabled slices and subslices to - * count the total enabled EU. - */ - for (s = 0; s < s_max; s++) { - if (!(s_enable & (0x1 << s))) - /* skip disabled slice */ - continue; - - for (ss = 0; ss < ss_max; ss++) { - u32 n_disabled; - - if (ss_disable & (0x1 << ss)) - /* skip disabled subslice */ - continue; - - n_disabled = hweight8(eu_disable[s] >> (ss * eu_max)); - - /* - * Record which subslices have 7 EUs. - */ - if (eu_max - n_disabled == 7) - info->subslice_7eu[s] |= 1 << ss; - - info->eu_total += eu_max - n_disabled; - } - } - - /* - * BDW is expected to always have a uniform distribution of EU across - * subslices with the exception that any one EU in any one subslice may - * be fused off for die recovery. - */ - info->eu_per_subslice = info->subslice_total ? - DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0; - - /* - * BDW supports slice power gating on devices with more than - * one slice. - */ - info->has_slice_pg = (info->slice_total > 1); - info->has_subslice_pg = 0; - info->has_eu_pg = 0; -} - -/* - * Determine various intel_device_info fields at runtime. - * - * Use it when either: - * - it's judged too laborious to fill n static structures with the limit - * when a simple if statement does the job, - * - run-time checks (eg read fuse/strap registers) are needed. - * - * This function needs to be called: - * - after the MMIO has been setup as we are reading registers, - * - after the PCH has been detected, - * - before the first usage of the fields it can tweak. - */ -static void intel_device_info_runtime_init(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_device_info *info; - enum pipe pipe; - - info = (struct intel_device_info *)&dev_priv->info; - - /* - * Skylake and Broxton currently don't expose the topmost plane as its - * use is exclusive with the legacy cursor and we only want to expose - * one of those, not both. Until we can safely expose the topmost plane - * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported, - * we don't expose the topmost plane at all to prevent ABI breakage - * down the line. - */ - if (IS_BROXTON(dev)) { - info->num_sprites[PIPE_A] = 2; - info->num_sprites[PIPE_B] = 2; - info->num_sprites[PIPE_C] = 1; - } else if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) - for_each_pipe(dev_priv, pipe) - info->num_sprites[pipe] = 2; - else - for_each_pipe(dev_priv, pipe) - info->num_sprites[pipe] = 1; - - if (i915.disable_display) { - DRM_INFO("Display disabled (module parameter)\n"); - info->num_pipes = 0; - } else if (info->num_pipes > 0 && - (IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) && - HAS_PCH_SPLIT(dev)) { - u32 fuse_strap = I915_READ(FUSE_STRAP); - u32 sfuse_strap = I915_READ(SFUSE_STRAP); - - /* - * SFUSE_STRAP is supposed to have a bit signalling the display - * is fused off. Unfortunately it seems that, at least in - * certain cases, fused off display means that PCH display - * reads don't land anywhere. In that case, we read 0s. - * - * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK - * should be set when taking over after the firmware. - */ - if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE || - sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED || - (dev_priv->pch_type == PCH_CPT && - !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { - DRM_INFO("Display fused off, disabling\n"); - info->num_pipes = 0; - } else if (fuse_strap & IVB_PIPE_C_DISABLE) { - DRM_INFO("PipeC fused off\n"); - info->num_pipes -= 1; - } - } else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) { - u32 dfsm = I915_READ(SKL_DFSM); - u8 disabled_mask = 0; - bool invalid; - int num_bits; - - if (dfsm & SKL_DFSM_PIPE_A_DISABLE) - disabled_mask |= BIT(PIPE_A); - if (dfsm & SKL_DFSM_PIPE_B_DISABLE) - disabled_mask |= BIT(PIPE_B); - if (dfsm & SKL_DFSM_PIPE_C_DISABLE) - disabled_mask |= BIT(PIPE_C); - - num_bits = hweight8(disabled_mask); - - switch (disabled_mask) { - case BIT(PIPE_A): - case BIT(PIPE_B): - case BIT(PIPE_A) | BIT(PIPE_B): - case BIT(PIPE_A) | BIT(PIPE_C): - invalid = true; - break; - default: - invalid = false; - } - - if (num_bits > info->num_pipes || invalid) - DRM_ERROR("invalid pipe fuse configuration: 0x%x\n", - disabled_mask); - else - info->num_pipes -= num_bits; - } - - /* Initialize slice/subslice/EU info */ - if (IS_CHERRYVIEW(dev)) - cherryview_sseu_info_init(dev); - else if (IS_BROADWELL(dev)) - broadwell_sseu_info_init(dev); - else if (INTEL_INFO(dev)->gen >= 9) - gen9_sseu_info_init(dev); - - info->has_snoop = !info->has_llc; - - /* Snooping is broken on BXT A stepping. */ - if (IS_BXT_REVID(dev, 0, BXT_REVID_A1)) - info->has_snoop = false; - - DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total); - DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total); - DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice); - DRM_DEBUG_DRIVER("EU total: %u\n", info->eu_total); - DRM_DEBUG_DRIVER("EU per subslice: %u\n", info->eu_per_subslice); - DRM_DEBUG_DRIVER("has slice power gating: %s\n", - info->has_slice_pg ? "y" : "n"); - DRM_DEBUG_DRIVER("has subslice power gating: %s\n", - info->has_subslice_pg ? "y" : "n"); - DRM_DEBUG_DRIVER("has EU power gating: %s\n", - info->has_eu_pg ? "y" : "n"); - - i915.enable_execlists = - intel_sanitize_enable_execlists(dev_priv, - i915.enable_execlists); - - /* - * i915.enable_ppgtt is read-only, so do an early pass to validate the - * user's requested state against the hardware/driver capabilities. We - * do this now so that we can print out any log messages once rather - * than every time we check intel_enable_ppgtt(). - */ - i915.enable_ppgtt = - intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt); - DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt); -} - static void intel_init_dpio(struct drm_i915_private *dev_priv) { /* @@ -1213,7 +825,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, return -ENODEV; /* Setup the write-once "constant" device info */ - device_info = (struct intel_device_info *)&dev_priv->info; + device_info = mkwrite_device_info(dev_priv); memcpy(device_info, match_info, sizeof(*device_info)); device_info->device_id = dev_priv->drm.pdev->device; @@ -1254,7 +866,7 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv, intel_display_crc_init(&dev_priv->drm); - i915_dump_device_info(dev_priv); + intel_device_info_dump(dev_priv); /* Not all pre-production machines fall into this category, only the * very first ones. Almost everything should work, except for maybe @@ -1368,6 +980,23 @@ static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) pci_dev_put(dev_priv->bridge_dev); } +static void intel_sanitize_options(struct drm_i915_private *dev_priv) +{ + i915.enable_execlists = + intel_sanitize_enable_execlists(dev_priv, + i915.enable_execlists); + + /* + * i915.enable_ppgtt is read-only, so do an early pass to validate the + * user's requested state against the hardware/driver capabilities. We + * do this now so that we can print out any log messages once rather + * than every time we check intel_enable_ppgtt(). + */ + i915.enable_ppgtt = + intel_sanitize_enable_ppgtt(dev_priv, i915.enable_ppgtt); + DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt); +} + /** * i915_driver_init_hw - setup state requiring device access * @dev_priv: device private @@ -1385,7 +1014,9 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) if (i915_inject_load_failure()) return -ENODEV; - intel_device_info_runtime_init(dev); + intel_device_info_runtime_init(dev_priv); + + intel_sanitize_options(dev_priv); ret = i915_ggtt_init_hw(dev); if (ret) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 594ddbba3a64..d33b370a057d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3750,6 +3750,16 @@ static inline void intel_register_dsm_handler(void) { return; } static inline void intel_unregister_dsm_handler(void) { return; } #endif /* CONFIG_ACPI */ +/* intel_device_info.c */ +static inline struct intel_device_info * +mkwrite_device_info(struct drm_i915_private *dev_priv) +{ + return (struct intel_device_info *)&dev_priv->info; +} + +void intel_device_info_runtime_init(struct drm_i915_private *dev_priv); +void intel_device_info_dump(struct drm_i915_private *dev_priv); + /* modesetting */ extern void intel_modeset_init_hw(struct drm_device *dev); extern void intel_modeset_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c new file mode 100644 index 000000000000..cba137f9ad3e --- /dev/null +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -0,0 +1,388 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, 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. + * + */ + +#include "i915_drv.h" + +void intel_device_info_dump(struct drm_i915_private *dev_priv) +{ + const struct intel_device_info *info = &dev_priv->info; + +#define PRINT_S(name) "%s" +#define SEP_EMPTY +#define PRINT_FLAG(name) info->name ? #name "," : "" +#define SEP_COMMA , + DRM_DEBUG_DRIVER("i915 device info: gen=%i, pciid=0x%04x rev=0x%02x flags=" + DEV_INFO_FOR_EACH_FLAG(PRINT_S, SEP_EMPTY), + info->gen, + dev_priv->drm.pdev->device, + dev_priv->drm.pdev->revision, + DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_COMMA)); +#undef PRINT_S +#undef SEP_EMPTY +#undef PRINT_FLAG +#undef SEP_COMMA +} + +static void cherryview_sseu_info_init(struct drm_i915_private *dev_priv) +{ + struct intel_device_info *info = mkwrite_device_info(dev_priv); + u32 fuse, eu_dis; + + fuse = I915_READ(CHV_FUSE_GT); + + info->slice_total = 1; + + if (!(fuse & CHV_FGT_DISABLE_SS0)) { + info->subslice_per_slice++; + eu_dis = fuse & (CHV_FGT_EU_DIS_SS0_R0_MASK | + CHV_FGT_EU_DIS_SS0_R1_MASK); + info->eu_total += 8 - hweight32(eu_dis); + } + + if (!(fuse & CHV_FGT_DISABLE_SS1)) { + info->subslice_per_slice++; + eu_dis = fuse & (CHV_FGT_EU_DIS_SS1_R0_MASK | + CHV_FGT_EU_DIS_SS1_R1_MASK); + info->eu_total += 8 - hweight32(eu_dis); + } + + info->subslice_total = info->subslice_per_slice; + /* + * CHV expected to always have a uniform distribution of EU + * across subslices. + */ + info->eu_per_subslice = info->subslice_total ? + info->eu_total / info->subslice_total : + 0; + /* + * CHV supports subslice power gating on devices with more than + * one subslice, and supports EU power gating on devices with + * more than one EU pair per subslice. + */ + info->has_slice_pg = 0; + info->has_subslice_pg = (info->subslice_total > 1); + info->has_eu_pg = (info->eu_per_subslice > 2); +} + +static void gen9_sseu_info_init(struct drm_i915_private *dev_priv) +{ + struct intel_device_info *info = mkwrite_device_info(dev_priv); + int s_max = 3, ss_max = 4, eu_max = 8; + int s, ss; + u32 fuse2, s_enable, ss_disable, eu_disable; + u8 eu_mask = 0xff; + + fuse2 = I915_READ(GEN8_FUSE2); + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT; + ss_disable = (fuse2 & GEN9_F2_SS_DIS_MASK) >> GEN9_F2_SS_DIS_SHIFT; + + info->slice_total = hweight32(s_enable); + /* + * The subslice disable field is global, i.e. it applies + * to each of the enabled slices. + */ + info->subslice_per_slice = ss_max - hweight32(ss_disable); + info->subslice_total = info->slice_total * info->subslice_per_slice; + + /* + * Iterate through enabled slices and subslices to + * count the total enabled EU. + */ + for (s = 0; s < s_max; s++) { + if (!(s_enable & BIT(s))) + /* skip disabled slice */ + continue; + + eu_disable = I915_READ(GEN9_EU_DISABLE(s)); + for (ss = 0; ss < ss_max; ss++) { + int eu_per_ss; + + if (ss_disable & BIT(ss)) + /* skip disabled subslice */ + continue; + + eu_per_ss = eu_max - hweight8((eu_disable >> (ss*8)) & + eu_mask); + + /* + * Record which subslice(s) has(have) 7 EUs. we + * can tune the hash used to spread work among + * subslices if they are unbalanced. + */ + if (eu_per_ss == 7) + info->subslice_7eu[s] |= BIT(ss); + + info->eu_total += eu_per_ss; + } + } + + /* + * SKL is expected to always have a uniform distribution + * of EU across subslices with the exception that any one + * EU in any one subslice may be fused off for die + * recovery. BXT is expected to be perfectly uniform in EU + * distribution. + */ + info->eu_per_subslice = info->subslice_total ? + DIV_ROUND_UP(info->eu_total, + info->subslice_total) : 0; + /* + * SKL supports slice power gating on devices with more than + * one slice, and supports EU power gating on devices with + * more than one EU pair per subslice. BXT supports subslice + * power gating on devices with more than one subslice, and + * supports EU power gating on devices with more than one EU + * pair per subslice. + */ + info->has_slice_pg = + (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) && + info->slice_total > 1; + info->has_subslice_pg = + IS_BROXTON(dev_priv) && info->subslice_total > 1; + info->has_eu_pg = info->eu_per_subslice > 2; + + if (IS_BROXTON(dev_priv)) { +#define IS_SS_DISABLED(_ss_disable, ss) (_ss_disable & BIT(ss)) + /* + * There is a HW issue in 2x6 fused down parts that requires + * Pooled EU to be enabled as a WA. The pool configuration + * changes depending upon which subslice is fused down. This + * doesn't affect if the device has all 3 subslices enabled. + */ + /* WaEnablePooledEuFor2x6:bxt */ + info->has_pooled_eu = ((info->subslice_per_slice == 3) || + (info->subslice_per_slice == 2 && + INTEL_REVID(dev_priv) < BXT_REVID_C0)); + + info->min_eu_in_pool = 0; + if (info->has_pooled_eu) { + if (IS_SS_DISABLED(ss_disable, 0) || + IS_SS_DISABLED(ss_disable, 2)) + info->min_eu_in_pool = 3; + else if (IS_SS_DISABLED(ss_disable, 1)) + info->min_eu_in_pool = 6; + else + info->min_eu_in_pool = 9; + } +#undef IS_SS_DISABLED + } +} + +static void broadwell_sseu_info_init(struct drm_i915_private *dev_priv) +{ + struct intel_device_info *info = mkwrite_device_info(dev_priv); + const int s_max = 3, ss_max = 3, eu_max = 8; + int s, ss; + u32 fuse2, eu_disable[s_max], s_enable, ss_disable; + + fuse2 = I915_READ(GEN8_FUSE2); + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT; + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT; + + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK; + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) | + ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) << + (32 - GEN8_EU_DIS0_S1_SHIFT)); + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) | + ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) << + (32 - GEN8_EU_DIS1_S2_SHIFT)); + + info->slice_total = hweight32(s_enable); + + /* + * The subslice disable field is global, i.e. it applies + * to each of the enabled slices. + */ + info->subslice_per_slice = ss_max - hweight32(ss_disable); + info->subslice_total = info->slice_total * info->subslice_per_slice; + + /* + * Iterate through enabled slices and subslices to + * count the total enabled EU. + */ + for (s = 0; s < s_max; s++) { + if (!(s_enable & (0x1 << s))) + /* skip disabled slice */ + continue; + + for (ss = 0; ss < ss_max; ss++) { + u32 n_disabled; + + if (ss_disable & (0x1 << ss)) + /* skip disabled subslice */ + continue; + + n_disabled = hweight8(eu_disable[s] >> (ss * eu_max)); + + /* + * Record which subslices have 7 EUs. + */ + if (eu_max - n_disabled == 7) + info->subslice_7eu[s] |= 1 << ss; + + info->eu_total += eu_max - n_disabled; + } + } + + /* + * BDW is expected to always have a uniform distribution of EU across + * subslices with the exception that any one EU in any one subslice may + * be fused off for die recovery. + */ + info->eu_per_subslice = info->subslice_total ? + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0; + + /* + * BDW supports slice power gating on devices with more than + * one slice. + */ + info->has_slice_pg = (info->slice_total > 1); + info->has_subslice_pg = 0; + info->has_eu_pg = 0; +} + +/* + * Determine various intel_device_info fields at runtime. + * + * Use it when either: + * - it's judged too laborious to fill n static structures with the limit + * when a simple if statement does the job, + * - run-time checks (eg read fuse/strap registers) are needed. + * + * This function needs to be called: + * - after the MMIO has been setup as we are reading registers, + * - after the PCH has been detected, + * - before the first usage of the fields it can tweak. + */ +void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) +{ + struct intel_device_info *info = mkwrite_device_info(dev_priv); + enum pipe pipe; + + /* + * Skylake and Broxton currently don't expose the topmost plane as its + * use is exclusive with the legacy cursor and we only want to expose + * one of those, not both. Until we can safely expose the topmost plane + * as a DRM_PLANE_TYPE_CURSOR with all the features exposed/supported, + * we don't expose the topmost plane at all to prevent ABI breakage + * down the line. + */ + if (IS_BROXTON(dev_priv)) { + info->num_sprites[PIPE_A] = 2; + info->num_sprites[PIPE_B] = 2; + info->num_sprites[PIPE_C] = 1; + } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + for_each_pipe(dev_priv, pipe) + info->num_sprites[pipe] = 2; + else + for_each_pipe(dev_priv, pipe) + info->num_sprites[pipe] = 1; + + if (i915.disable_display) { + DRM_INFO("Display disabled (module parameter)\n"); + info->num_pipes = 0; + } else if (info->num_pipes > 0 && + (IS_GEN7(dev_priv) || IS_GEN8(dev_priv)) && + HAS_PCH_SPLIT(dev_priv)) { + u32 fuse_strap = I915_READ(FUSE_STRAP); + u32 sfuse_strap = I915_READ(SFUSE_STRAP); + + /* + * SFUSE_STRAP is supposed to have a bit signalling the display + * is fused off. Unfortunately it seems that, at least in + * certain cases, fused off display means that PCH display + * reads don't land anywhere. In that case, we read 0s. + * + * On CPT/PPT, we can detect this case as SFUSE_STRAP_FUSE_LOCK + * should be set when taking over after the firmware. + */ + if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE || + sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED || + (dev_priv->pch_type == PCH_CPT && + !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { + DRM_INFO("Display fused off, disabling\n"); + info->num_pipes = 0; + } else if (fuse_strap & IVB_PIPE_C_DISABLE) { + DRM_INFO("PipeC fused off\n"); + info->num_pipes -= 1; + } + } else if (info->num_pipes > 0 && IS_GEN9(dev_priv)) { + u32 dfsm = I915_READ(SKL_DFSM); + u8 disabled_mask = 0; + bool invalid; + int num_bits; + + if (dfsm & SKL_DFSM_PIPE_A_DISABLE) + disabled_mask |= BIT(PIPE_A); + if (dfsm & SKL_DFSM_PIPE_B_DISABLE) + disabled_mask |= BIT(PIPE_B); + if (dfsm & SKL_DFSM_PIPE_C_DISABLE) + disabled_mask |= BIT(PIPE_C); + + num_bits = hweight8(disabled_mask); + + switch (disabled_mask) { + case BIT(PIPE_A): + case BIT(PIPE_B): + case BIT(PIPE_A) | BIT(PIPE_B): + case BIT(PIPE_A) | BIT(PIPE_C): + invalid = true; + break; + default: + invalid = false; + } + + if (num_bits > info->num_pipes || invalid) + DRM_ERROR("invalid pipe fuse configuration: 0x%x\n", + disabled_mask); + else + info->num_pipes -= num_bits; + } + + /* Initialize slice/subslice/EU info */ + if (IS_CHERRYVIEW(dev_priv)) + cherryview_sseu_info_init(dev_priv); + else if (IS_BROADWELL(dev_priv)) + broadwell_sseu_info_init(dev_priv); + else if (INTEL_INFO(dev_priv)->gen >= 9) + gen9_sseu_info_init(dev_priv); + + info->has_snoop = !info->has_llc; + + /* Snooping is broken on BXT A stepping. */ + if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) + info->has_snoop = false; + + DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total); + DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total); + DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice); + DRM_DEBUG_DRIVER("EU total: %u\n", info->eu_total); + DRM_DEBUG_DRIVER("EU per subslice: %u\n", info->eu_per_subslice); + DRM_DEBUG_DRIVER("has slice power gating: %s\n", + info->has_slice_pg ? "y" : "n"); + DRM_DEBUG_DRIVER("has subslice power gating: %s\n", + info->has_subslice_pg ? "y" : "n"); + DRM_DEBUG_DRIVER("has EU power gating: %s\n", + info->has_eu_pg ? "y" : "n"); +} -- cgit v1.2.3 From fb93942033dfe7b4b87bba516f9b551da0bac970 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 Jul 2016 10:40:21 +0100 Subject: drm/i915: Remove use of dev_priv->dev backpointer in __i915_printk() As we can just directly use drm_dev->drm.dev, we do not need the drm_dev->dev backpointer anymore and can also loose the warning about order of __i915_printk() and our initialisation (which is now always safe). Signed-off-by: Chris Wilson Cc: Imre Deak Link: http://patchwork.freedesktop.org/patch/msgid/1467711623-2905-2-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/i915_drv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 87295f6e5520..fa72b73cb180 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -77,7 +77,7 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level, const char *fmt, ...) { static bool shown_bug_once; - struct device *dev = dev_priv->dev->dev; + struct device *dev = dev_priv->drm.dev; bool is_error = level[1] <= KERN_ERR[1]; bool is_debug = level[1] == KERN_DEBUG[1]; struct va_format vaf; @@ -1234,7 +1234,6 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) return ret; } - /* Must be set before calling __i915_printk */ dev_priv->drm.pdev = pdev; dev_priv->drm.dev_private = dev_priv; dev_priv->dev = &dev_priv->drm; -- cgit v1.2.3 From ded8b07d4c2827811215d92be4c97426ce7f1999 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 Jul 2016 10:40:22 +0100 Subject: drm/i915: Remove impossible tests for dev->dev_private If we have a drm_device, we have a drm_i915_private (since they are the same). Signed-off-by: Chris Wilson Cc: Imre Deak Link: http://patchwork.freedesktop.org/patch/msgid/1467711623-2905-3-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/i915_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index fa72b73cb180..595029bc55a3 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1556,7 +1556,7 @@ int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state) { int error; - if (!dev || !dev->dev_private) { + if (!dev) { DRM_ERROR("dev: %p\n", dev); DRM_ERROR("DRM not initialized, aborting suspend.\n"); return -ENODEV; @@ -1848,7 +1848,7 @@ static int i915_pm_suspend(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); - if (!drm_dev || !drm_dev->dev_private) { + if (!drm_dev) { dev_err(dev, "DRM not initialized, aborting suspend.\n"); return -ENODEV; } -- cgit v1.2.3 From 91c8a326a192117219d5b9b980244c3662e35404 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 Jul 2016 10:40:23 +0100 Subject: drm/i915: Convert dev_priv->dev backpointers to dev_priv->drm Since drm_i915_private is now a subclass of drm_device we do not need to chase the drm_i915_private->dev backpointer and can instead simply access drm_i915_private->drm directly. text data bss dec hex filename 1068757 4565 416 1073738 10624a drivers/gpu/drm/i915/i915.ko 1066949 4565 416 1071930 105b3a drivers/gpu/drm/i915/i915.ko Created by the coccinelle script: @@ struct drm_i915_private *d; identifier i; @@ ( - d->dev->i + d->drm.i | - d->dev + &d->drm ) and for good measure the dev_priv->dev backpointer was removed entirely. Signed-off-by: Chris Wilson Reviewed-by: Matthew Auld Link: http://patchwork.freedesktop.org/patch/msgid/1467711623-2905-4-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 16 ++++----- drivers/gpu/drm/i915/i915_drv.c | 39 ++++++++++---------- drivers/gpu/drm/i915/i915_drv.h | 22 +++++++----- drivers/gpu/drm/i915/i915_gem.c | 14 ++++---- drivers/gpu/drm/i915/i915_gem_context.c | 6 ++-- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 +-- drivers/gpu/drm/i915/i915_gem_gtt.c | 8 ++--- drivers/gpu/drm/i915/i915_gem_render_state.c | 2 +- drivers/gpu/drm/i915/i915_gem_shrinker.c | 8 ++--- drivers/gpu/drm/i915/i915_gpu_error.c | 5 +-- drivers/gpu/drm/i915/i915_guc_submission.c | 2 +- drivers/gpu/drm/i915/i915_irq.c | 36 +++++++++---------- drivers/gpu/drm/i915/i915_trace.h | 20 +++++------ drivers/gpu/drm/i915/intel_audio.c | 12 +++---- drivers/gpu/drm/i915/intel_bios.c | 2 +- drivers/gpu/drm/i915/intel_csr.c | 4 +-- drivers/gpu/drm/i915/intel_display.c | 54 ++++++++++++++-------------- drivers/gpu/drm/i915/intel_dp.c | 30 ++++++++-------- drivers/gpu/drm/i915/intel_dpll_mgr.c | 2 +- drivers/gpu/drm/i915/intel_fbc.c | 4 +-- drivers/gpu/drm/i915/intel_fbdev.c | 6 ++-- drivers/gpu/drm/i915/intel_fifo_underrun.c | 12 ++++--- drivers/gpu/drm/i915/intel_guc_loader.c | 2 +- drivers/gpu/drm/i915/intel_hdmi.c | 2 +- drivers/gpu/drm/i915/intel_hotplug.c | 8 ++--- drivers/gpu/drm/i915/intel_i2c.c | 6 ++-- drivers/gpu/drm/i915/intel_lrc.c | 14 ++++---- drivers/gpu/drm/i915/intel_opregion.c | 11 +++--- drivers/gpu/drm/i915/intel_overlay.c | 24 +++++++------ drivers/gpu/drm/i915/intel_panel.c | 6 ++-- drivers/gpu/drm/i915/intel_pm.c | 29 +++++++-------- drivers/gpu/drm/i915/intel_ringbuffer.c | 18 +++++----- drivers/gpu/drm/i915/intel_runtime_pm.c | 26 +++++++------- drivers/gpu/drm/i915/intel_sdvo.c | 2 +- drivers/gpu/drm/i915/intel_uncore.c | 6 ++-- 35 files changed, 236 insertions(+), 226 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 8cc453731567..a59e0caeda64 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -440,15 +440,15 @@ static void print_context_stats(struct seq_file *m, memset(&stats, 0, sizeof(stats)); - mutex_lock(&dev_priv->dev->struct_mutex); + mutex_lock(&dev_priv->drm.struct_mutex); if (dev_priv->kernel_context) per_file_ctx_stats(0, dev_priv->kernel_context, &stats); - list_for_each_entry(file, &dev_priv->dev->filelist, lhead) { + list_for_each_entry(file, &dev_priv->drm.filelist, lhead) { struct drm_i915_file_private *fpriv = file->driver_priv; idr_for_each(&fpriv->context_idr, per_file_ctx_stats, &stats); } - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); print_file_stats(m, "[k]contexts", stats); } @@ -2797,8 +2797,8 @@ static int i915_runtime_pm_status(struct seq_file *m, void *unused) seq_printf(m, "Device Power Management (CONFIG_PM) disabled\n"); #endif seq_printf(m, "PCI device power state: %s [%d]\n", - pci_power_name(dev_priv->dev->pdev->current_state), - dev_priv->dev->pdev->current_state); + pci_power_name(dev_priv->drm.pdev->current_state), + dev_priv->drm.pdev->current_state); return 0; } @@ -5098,7 +5098,7 @@ i915_cache_sharing_get(void *data, u64 *val) snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); intel_runtime_pm_put(dev_priv); - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); *val = (snpcr & GEN6_MBC_SNPCR_MASK) >> GEN6_MBC_SNPCR_SHIFT; @@ -5483,7 +5483,7 @@ void intel_display_crc_init(struct drm_device *dev) int i915_debugfs_register(struct drm_i915_private *dev_priv) { - struct drm_minor *minor = dev_priv->dev->primary; + struct drm_minor *minor = dev_priv->drm.primary; int ret, i; ret = i915_forcewake_create(minor->debugfs_root, minor); @@ -5511,7 +5511,7 @@ int i915_debugfs_register(struct drm_i915_private *dev_priv) void i915_debugfs_unregister(struct drm_i915_private *dev_priv) { - struct drm_minor *minor = dev_priv->dev->primary; + struct drm_minor *minor = dev_priv->drm.primary; int i; drm_debugfs_remove_files(i915_debugfs_list, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 595029bc55a3..694edac2c703 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -687,7 +687,7 @@ out: static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) { struct apertures_struct *ap; - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; struct i915_ggtt *ggtt = &dev_priv->ggtt; bool primary; int ret; @@ -889,7 +889,7 @@ err_workqueues: */ static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) { - i915_gem_load_cleanup(dev_priv->dev); + i915_gem_load_cleanup(&dev_priv->drm); i915_workqueues_cleanup(dev_priv); } @@ -944,7 +944,7 @@ static void i915_mmio_cleanup(struct drm_device *dev) */ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; int ret; if (i915_inject_load_failure()) @@ -973,7 +973,7 @@ put_bridge: */ static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; intel_uncore_fini(dev_priv); i915_mmio_cleanup(dev); @@ -1006,7 +1006,7 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv) */ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct i915_ggtt *ggtt = &dev_priv->ggtt; uint32_t aperture_size; int ret; @@ -1125,7 +1125,7 @@ out_ggtt: */ static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct i915_ggtt *ggtt = &dev_priv->ggtt; if (dev->pdev->msi_enabled) @@ -1146,7 +1146,7 @@ static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) */ static void i915_driver_register(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; i915_gem_shrinker_init(dev_priv); @@ -1197,9 +1197,9 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) acpi_video_unregister(); intel_opregion_unregister(dev_priv); - i915_teardown_sysfs(dev_priv->dev); + i915_teardown_sysfs(&dev_priv->drm); i915_debugfs_unregister(dev_priv); - drm_dev_unregister(dev_priv->dev); + drm_dev_unregister(&dev_priv->drm); i915_gem_shrinker_cleanup(dev_priv); } @@ -1236,7 +1236,6 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) dev_priv->drm.pdev = pdev; dev_priv->drm.dev_private = dev_priv; - dev_priv->dev = &dev_priv->drm; ret = pci_enable_device(pdev); if (ret) @@ -1264,13 +1263,13 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) * to the role/effect of the given init step. */ if (INTEL_INFO(dev_priv)->num_pipes) { - ret = drm_vblank_init(dev_priv->dev, + ret = drm_vblank_init(&dev_priv->drm, INTEL_INFO(dev_priv)->num_pipes); if (ret) goto out_cleanup_hw; } - ret = i915_load_modeset_init(dev_priv->dev); + ret = i915_load_modeset_init(&dev_priv->drm); if (ret < 0) goto out_cleanup_vblank; @@ -1283,7 +1282,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; out_cleanup_vblank: - drm_vblank_cleanup(dev_priv->dev); + drm_vblank_cleanup(&dev_priv->drm); out_cleanup_hw: i915_driver_cleanup_hw(dev_priv); out_cleanup_mmio: @@ -1402,7 +1401,7 @@ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) static void intel_suspend_encoders(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct intel_encoder *encoder; drm_modeset_lock_all(dev); @@ -1770,7 +1769,7 @@ int i915_resume_switcheroo(struct drm_device *dev) */ int i915_reset(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct i915_gpu_error *error = &dev_priv->gpu_error; unsigned reset_counter; int ret; @@ -1861,7 +1860,7 @@ static int i915_pm_suspend(struct device *dev) static int i915_pm_suspend_late(struct device *dev) { - struct drm_device *drm_dev = dev_to_i915(dev)->dev; + struct drm_device *drm_dev = &dev_to_i915(dev)->drm; /* * We have a suspend ordering issue with the snd-hda driver also @@ -1880,7 +1879,7 @@ static int i915_pm_suspend_late(struct device *dev) static int i915_pm_poweroff_late(struct device *dev) { - struct drm_device *drm_dev = dev_to_i915(dev)->dev; + struct drm_device *drm_dev = &dev_to_i915(dev)->drm; if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; @@ -1890,7 +1889,7 @@ static int i915_pm_poweroff_late(struct device *dev) static int i915_pm_resume_early(struct device *dev) { - struct drm_device *drm_dev = dev_to_i915(dev)->dev; + struct drm_device *drm_dev = &dev_to_i915(dev)->drm; if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; @@ -1900,7 +1899,7 @@ static int i915_pm_resume_early(struct device *dev) static int i915_pm_resume(struct device *dev) { - struct drm_device *drm_dev = dev_to_i915(dev)->dev; + struct drm_device *drm_dev = &dev_to_i915(dev)->drm; if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; @@ -2278,7 +2277,7 @@ err1: static int vlv_resume_prepare(struct drm_i915_private *dev_priv, bool rpm_resume) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; int err; int ret; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d33b370a057d..c269e0ad4057 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -320,15 +320,16 @@ struct i915_hotplug { for_each_if ((__ports_mask) & (1 << (__port))) #define for_each_crtc(dev, crtc) \ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + list_for_each_entry(crtc, &(dev)->mode_config.crtc_list, head) #define for_each_intel_plane(dev, intel_plane) \ list_for_each_entry(intel_plane, \ - &dev->mode_config.plane_list, \ + &(dev)->mode_config.plane_list, \ base.head) #define for_each_intel_plane_mask(dev, intel_plane, plane_mask) \ - list_for_each_entry(intel_plane, &dev->mode_config.plane_list, \ + list_for_each_entry(intel_plane, \ + &(dev)->mode_config.plane_list, \ base.head) \ for_each_if ((plane_mask) & \ (1 << drm_plane_index(&intel_plane->base))) @@ -339,11 +340,15 @@ struct i915_hotplug { base.head) \ for_each_if ((intel_plane)->pipe == (intel_crtc)->pipe) -#define for_each_intel_crtc(dev, intel_crtc) \ - list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) +#define for_each_intel_crtc(dev, intel_crtc) \ + list_for_each_entry(intel_crtc, \ + &(dev)->mode_config.crtc_list, \ + base.head) -#define for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) \ - list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) \ +#define for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) \ + list_for_each_entry(intel_crtc, \ + &(dev)->mode_config.crtc_list, \ + base.head) \ for_each_if ((crtc_mask) & (1 << drm_crtc_index(&intel_crtc->base))) #define for_each_intel_encoder(dev, intel_encoder) \ @@ -353,7 +358,7 @@ struct i915_hotplug { #define for_each_intel_connector(dev, intel_connector) \ list_for_each_entry(intel_connector, \ - &dev->mode_config.connector_list, \ + &(dev)->mode_config.connector_list, \ base.head) #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ @@ -1718,7 +1723,6 @@ struct intel_wm_config { struct drm_i915_private { struct drm_device drm; - struct drm_device *dev; struct kmem_cache *objects; struct kmem_cache *vmas; struct kmem_cache *requests; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 20123c09bc18..8f50919ba9b4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1651,7 +1651,7 @@ __i915_gem_request_retire__upto(struct drm_i915_gem_request *req) struct intel_engine_cs *engine = req->engine; struct drm_i915_gem_request *tmp; - lockdep_assert_held(&engine->i915->dev->struct_mutex); + lockdep_assert_held(&engine->i915->drm.struct_mutex); if (list_empty(&req->list)) return; @@ -1680,7 +1680,7 @@ i915_wait_request(struct drm_i915_gem_request *req) interruptible = dev_priv->mm.interruptible; - BUG_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); + BUG_ON(!mutex_is_locked(&dev_priv->drm.struct_mutex)); ret = __i915_wait_request(req, interruptible, NULL, NULL); if (ret) @@ -3254,7 +3254,7 @@ void i915_gem_retire_requests(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; - lockdep_assert_held(&dev_priv->dev->struct_mutex); + lockdep_assert_held(&dev_priv->drm.struct_mutex); if (dev_priv->gt.active_engines == 0) return; @@ -3278,7 +3278,7 @@ i915_gem_retire_work_handler(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), gt.retire_work.work); - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; /* Come back later if the device is busy... */ if (mutex_trylock(&dev->struct_mutex)) { @@ -3301,7 +3301,7 @@ i915_gem_idle_work_handler(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), gt.idle_work.work); - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct intel_engine_cs *engine; unsigned int stuck_engines; bool rearm_hangcheck; @@ -3713,7 +3713,7 @@ int i915_gem_wait_for_idle(struct drm_i915_private *dev_priv) struct intel_engine_cs *engine; int ret; - lockdep_assert_held(&dev_priv->dev->struct_mutex); + lockdep_assert_held(&dev_priv->drm.struct_mutex); for_each_engine(engine, dev_priv) { if (engine->last_context == NULL) @@ -5252,7 +5252,7 @@ init_engine_lists(struct intel_engine_cs *engine) void i915_gem_load_init_fences(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; if (INTEL_INFO(dev_priv)->gen >= 7 && !IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index b4bba8a76191..3c97f0e7a003 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -154,7 +154,7 @@ void i915_gem_context_free(struct kref *ctx_ref) struct i915_gem_context *ctx = container_of(ctx_ref, typeof(*ctx), ref); int i; - lockdep_assert_held(&ctx->i915->dev->struct_mutex); + lockdep_assert_held(&ctx->i915->drm.struct_mutex); trace_i915_context_free(ctx); /* @@ -465,7 +465,7 @@ void i915_gem_context_lost(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; - lockdep_assert_held(&dev_priv->dev->struct_mutex); + lockdep_assert_held(&dev_priv->drm.struct_mutex); for_each_engine(engine, dev_priv) { if (engine->last_context) { @@ -895,7 +895,7 @@ int i915_switch_context(struct drm_i915_gem_request *req) struct intel_engine_cs *engine = req->engine; WARN_ON(i915.enable_execlists); - lockdep_assert_held(&req->i915->dev->struct_mutex); + lockdep_assert_held(&req->i915->drm.struct_mutex); if (!req->ctx->engine[engine->id].state) { struct i915_gem_context *to = req->ctx; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 3a04d37be4e9..1978633e7549 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1328,10 +1328,10 @@ gen8_dispatch_bsd_ring(struct drm_i915_private *dev_priv, struct drm_file *file) /* Check whether the file_priv has already selected one ring. */ if ((int)file_priv->bsd_ring < 0) { /* If not, use the ping-pong mechanism to select one. */ - mutex_lock(&dev_priv->dev->struct_mutex); + mutex_lock(&dev_priv->drm.struct_mutex); file_priv->bsd_ring = dev_priv->mm.bsd_ring_dispatch_index; dev_priv->mm.bsd_ring_dispatch_index ^= 1; - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); } return file_priv->bsd_ring; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 9d6ea275be89..365fe65950e1 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -153,7 +153,7 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, #endif /* Early VLV doesn't have this */ - if (IS_VALLEYVIEW(dev_priv) && dev_priv->dev->pdev->revision < 0xb) { + if (IS_VALLEYVIEW(dev_priv) && dev_priv->drm.pdev->revision < 0xb) { DRM_DEBUG_DRIVER("disabling PPGTT on pre-B3 step VLV\n"); return 0; } @@ -2115,7 +2115,7 @@ static void i915_address_space_init(struct i915_address_space *vm, struct drm_i915_private *dev_priv) { drm_mm_init(&vm->mm, vm->start, vm->total); - vm->dev = dev_priv->dev; + vm->dev = &dev_priv->drm; INIT_LIST_HEAD(&vm->active_list); INIT_LIST_HEAD(&vm->inactive_list); list_add_tail(&vm->global_link, &dev_priv->vm_list); @@ -3179,7 +3179,7 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt) struct drm_i915_private *dev_priv = to_i915(dev); int ret; - ret = intel_gmch_probe(dev_priv->bridge_dev, dev_priv->dev->pdev, NULL); + ret = intel_gmch_probe(dev_priv->bridge_dev, dev_priv->drm.pdev, NULL); if (!ret) { DRM_ERROR("failed to set up gmch\n"); return -EIO; @@ -3188,7 +3188,7 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt) intel_gtt_get(&ggtt->base.total, &ggtt->stolen_size, &ggtt->mappable_base, &ggtt->mappable_end); - ggtt->do_idle_maps = needs_idle_maps(dev_priv->dev); + ggtt->do_idle_maps = needs_idle_maps(&dev_priv->drm); ggtt->base.insert_page = i915_ggtt_insert_page; ggtt->base.insert_entries = i915_ggtt_insert_entries; ggtt->base.clear_range = i915_ggtt_clear_range; diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index b7c1b5fb61ea..f75bbd67a13a 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -58,7 +58,7 @@ static int render_state_init(struct render_state *so, if (so->rodata->batch_items * 4 > 4096) return -EINVAL; - so->obj = i915_gem_object_create(dev_priv->dev, 4096); + so->obj = i915_gem_object_create(&dev_priv->drm, 4096); if (IS_ERR(so->obj)) return PTR_ERR(so->obj); diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index 1bf14544d8ad..067632ad2f29 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -257,7 +257,7 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) { struct drm_i915_private *dev_priv = container_of(shrinker, struct drm_i915_private, mm.shrinker); - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_i915_gem_object *obj; unsigned long count; bool unlock; @@ -288,7 +288,7 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) { struct drm_i915_private *dev_priv = container_of(shrinker, struct drm_i915_private, mm.shrinker); - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; unsigned long freed; bool unlock; @@ -323,7 +323,7 @@ i915_gem_shrinker_lock_uninterruptible(struct drm_i915_private *dev_priv, { unsigned long timeout = msecs_to_jiffies(timeout_ms) + 1; - while (!i915_gem_shrinker_lock(dev_priv->dev, &slu->unlock)) { + while (!i915_gem_shrinker_lock(&dev_priv->drm, &slu->unlock)) { schedule_timeout_killable(1); if (fatal_signal_pending(current)) return false; @@ -344,7 +344,7 @@ i915_gem_shrinker_unlock_uninterruptible(struct drm_i915_private *dev_priv, { dev_priv->mm.interruptible = slu->was_interruptible; if (slu->unlock) - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); } static int diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 4e8cacfc4e48..9d73d2216adc 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1276,7 +1276,7 @@ static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, static void i915_capture_reg_state(struct drm_i915_private *dev_priv, struct drm_i915_error_state *error) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; int i; /* General organization @@ -1446,7 +1446,8 @@ void i915_capture_error_state(struct drm_i915_private *dev_priv, DRM_INFO("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n"); 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->dev->primary->index); + DRM_INFO("GPU crash dump saved to /sys/class/drm/card%d/error\n", + dev_priv->drm.primary->index); warned = true; } } diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index 3f9e3fe98faf..bfc8bf672f2d 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -622,7 +622,7 @@ gem_allocate_guc_obj(struct drm_i915_private *dev_priv, u32 size) { struct drm_i915_gem_object *obj; - obj = i915_gem_object_create(dev_priv->dev, size); + obj = i915_gem_object_create(&dev_priv->drm, size); if (IS_ERR(obj)) return NULL; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 3eadc8375449..b77d808b71cd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -378,7 +378,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) ~dev_priv->pm_rps_events); spin_unlock_irq(&dev_priv->irq_lock); - synchronize_irq(dev_priv->dev->irq); + synchronize_irq(dev_priv->drm.irq); /* Now that we will not be generating any more work, flush any * outsanding tasks. As we are called on the RPS idle path, @@ -566,7 +566,7 @@ i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 enable_mask; if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev, + enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm, status_mask); else enable_mask = status_mask << 16; @@ -580,7 +580,7 @@ i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, u32 enable_mask; if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - enable_mask = vlv_get_pipestat_enable_mask(dev_priv->dev, + enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm, status_mask); else enable_mask = status_mask << 16; @@ -1175,7 +1175,7 @@ static void ivybridge_parity_work(struct work_struct *work) * In order to prevent a get/put style interface, acquire struct mutex * any time we access those registers. */ - mutex_lock(&dev_priv->dev->struct_mutex); + mutex_lock(&dev_priv->drm.struct_mutex); /* If we've screwed up tracking, just let the interrupt fire again */ if (WARN_ON(!dev_priv->l3_parity.which_slice)) @@ -1211,7 +1211,7 @@ static void ivybridge_parity_work(struct work_struct *work) parity_event[4] = kasprintf(GFP_KERNEL, "SLICE=%d", slice); parity_event[5] = NULL; - kobject_uevent_env(&dev_priv->dev->primary->kdev->kobj, + kobject_uevent_env(&dev_priv->drm.primary->kdev->kobj, KOBJ_CHANGE, parity_event); DRM_DEBUG("Parity error: Slice = %d, Row = %d, Bank = %d, Sub bank = %d.\n", @@ -1231,7 +1231,7 @@ out: gen5_enable_gt_irq(dev_priv, GT_PARITY_ERROR(dev_priv)); spin_unlock_irq(&dev_priv->irq_lock); - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); } static void ivybridge_parity_error_irq_handler(struct drm_i915_private *dev_priv, @@ -1513,7 +1513,7 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, entry = &pipe_crc->entries[head]; - entry->frame = dev_priv->dev->driver->get_vblank_counter(dev_priv->dev, + entry->frame = dev_priv->drm.driver->get_vblank_counter(&dev_priv->drm, pipe); entry->crc[0] = crc0; entry->crc[1] = crc1; @@ -1611,7 +1611,7 @@ static bool intel_pipe_handle_vblank(struct drm_i915_private *dev_priv, { bool ret; - ret = drm_handle_vblank(dev_priv->dev, pipe); + ret = drm_handle_vblank(&dev_priv->drm, pipe); if (ret) intel_finish_page_flip_mmio(dev_priv, pipe); @@ -2500,7 +2500,7 @@ static void i915_error_wake_up(struct drm_i915_private *dev_priv) */ static void i915_reset_and_wakeup(struct drm_i915_private *dev_priv) { - struct kobject *kobj = &dev_priv->dev->primary->kdev->kobj; + struct kobject *kobj = &dev_priv->drm.primary->kdev->kobj; char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL }; @@ -3402,7 +3402,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, spin_unlock_irq(&dev_priv->irq_lock); /* make sure we're done processing display irqs */ - synchronize_irq(dev_priv->dev->irq); + synchronize_irq(dev_priv->drm.irq); } static void cherryview_irq_preinstall(struct drm_device *dev) @@ -3428,7 +3428,7 @@ static u32 intel_hpd_enabled_irqs(struct drm_i915_private *dev_priv, struct intel_encoder *encoder; u32 enabled_irqs = 0; - for_each_intel_encoder(dev_priv->dev, encoder) + for_each_intel_encoder(&dev_priv->drm, encoder) if (dev_priv->hotplug.stats[encoder->hpd_pin].state == HPD_ENABLED) enabled_irqs |= hpd[encoder->hpd_pin]; @@ -4510,7 +4510,7 @@ static void i965_irq_uninstall(struct drm_device * dev) */ void intel_irq_init(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; intel_hpd_init_work(dev_priv); @@ -4644,7 +4644,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv) */ dev_priv->pm.irqs_enabled = true; - return drm_irq_install(dev_priv->dev, dev_priv->dev->pdev->irq); + return drm_irq_install(&dev_priv->drm, dev_priv->drm.pdev->irq); } /** @@ -4656,7 +4656,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv) */ void intel_irq_uninstall(struct drm_i915_private *dev_priv) { - drm_irq_uninstall(dev_priv->dev); + drm_irq_uninstall(&dev_priv->drm); intel_hpd_cancel_work(dev_priv); dev_priv->pm.irqs_enabled = false; } @@ -4670,9 +4670,9 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) */ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) { - dev_priv->dev->driver->irq_uninstall(dev_priv->dev); + dev_priv->drm.driver->irq_uninstall(&dev_priv->drm); dev_priv->pm.irqs_enabled = false; - synchronize_irq(dev_priv->dev->irq); + synchronize_irq(dev_priv->drm.irq); } /** @@ -4685,6 +4685,6 @@ void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv) { dev_priv->pm.irqs_enabled = true; - dev_priv->dev->driver->irq_preinstall(dev_priv->dev); - dev_priv->dev->driver->irq_postinstall(dev_priv->dev); + dev_priv->drm.driver->irq_preinstall(&dev_priv->drm); + dev_priv->drm.driver->irq_postinstall(&dev_priv->drm); } diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index f59cf07184ae..534154e05fbe 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -118,7 +118,7 @@ TRACE_EVENT(i915_gem_shrink, ), TP_fast_assign( - __entry->dev = i915->dev->primary->index; + __entry->dev = i915->drm.primary->index; __entry->target = target; __entry->flags = flags; ), @@ -462,7 +462,7 @@ TRACE_EVENT(i915_gem_ring_sync_to, ), TP_fast_assign( - __entry->dev = from->i915->dev->primary->index; + __entry->dev = from->i915->drm.primary->index; __entry->sync_from = from->id; __entry->sync_to = to_req->engine->id; __entry->seqno = i915_gem_request_get_seqno(req); @@ -486,7 +486,7 @@ TRACE_EVENT(i915_gem_ring_dispatch, ), TP_fast_assign( - __entry->dev = req->i915->dev->primary->index; + __entry->dev = req->i915->drm.primary->index; __entry->ring = req->engine->id; __entry->seqno = req->seqno; __entry->flags = flags; @@ -509,7 +509,7 @@ TRACE_EVENT(i915_gem_ring_flush, ), TP_fast_assign( - __entry->dev = req->i915->dev->primary->index; + __entry->dev = req->i915->drm.primary->index; __entry->ring = req->engine->id; __entry->invalidate = invalidate; __entry->flush = flush; @@ -531,7 +531,7 @@ DECLARE_EVENT_CLASS(i915_gem_request, ), TP_fast_assign( - __entry->dev = req->i915->dev->primary->index; + __entry->dev = req->i915->drm.primary->index; __entry->ring = req->engine->id; __entry->seqno = req->seqno; ), @@ -556,7 +556,7 @@ TRACE_EVENT(i915_gem_request_notify, ), TP_fast_assign( - __entry->dev = engine->i915->dev->primary->index; + __entry->dev = engine->i915->drm.primary->index; __entry->ring = engine->id; __entry->seqno = intel_engine_get_seqno(engine); ), @@ -593,11 +593,11 @@ TRACE_EVENT(i915_gem_request_wait_begin, * less desirable. */ TP_fast_assign( - __entry->dev = req->i915->dev->primary->index; + __entry->dev = req->i915->drm.primary->index; __entry->ring = req->engine->id; __entry->seqno = req->seqno; __entry->blocking = - mutex_is_locked(&req->i915->dev->struct_mutex); + mutex_is_locked(&req->i915->drm.struct_mutex); ), TP_printk("dev=%u, ring=%u, seqno=%u, blocking=%s", @@ -746,7 +746,7 @@ DECLARE_EVENT_CLASS(i915_context, TP_fast_assign( __entry->ctx = ctx; __entry->vm = ctx->ppgtt ? &ctx->ppgtt->base : NULL; - __entry->dev = ctx->i915->dev->primary->index; + __entry->dev = ctx->i915->drm.primary->index; ), TP_printk("dev=%u, ctx=%p, ctx_vm=%p", @@ -786,7 +786,7 @@ TRACE_EVENT(switch_mm, __entry->ring = engine->id; __entry->to = to; __entry->vm = to->ppgtt? &to->ppgtt->base : NULL; - __entry->dev = engine->i915->dev->primary->index; + __entry->dev = engine->i915->drm.primary->index; ), TP_printk("dev=%u, ring=%u, ctx=%p, ctx_vm=%p", diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index e2e4d4c59e85..161f6c2bca36 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -749,14 +749,14 @@ static int i915_audio_component_bind(struct device *i915_dev, if (WARN_ON(acomp->ops || acomp->dev)) return -EEXIST; - drm_modeset_lock_all(dev_priv->dev); + drm_modeset_lock_all(&dev_priv->drm); acomp->ops = &i915_audio_component_ops; acomp->dev = i915_dev; BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS); for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++) acomp->aud_sample_rate[i] = 0; dev_priv->audio_component = acomp; - drm_modeset_unlock_all(dev_priv->dev); + drm_modeset_unlock_all(&dev_priv->drm); return 0; } @@ -767,11 +767,11 @@ static void i915_audio_component_unbind(struct device *i915_dev, struct i915_audio_component *acomp = data; struct drm_i915_private *dev_priv = dev_to_i915(i915_dev); - drm_modeset_lock_all(dev_priv->dev); + drm_modeset_lock_all(&dev_priv->drm); acomp->ops = NULL; acomp->dev = NULL; dev_priv->audio_component = NULL; - drm_modeset_unlock_all(dev_priv->dev); + drm_modeset_unlock_all(&dev_priv->drm); } static const struct component_ops i915_audio_component_bind_ops = { @@ -799,7 +799,7 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv) { int ret; - ret = component_add(dev_priv->dev->dev, &i915_audio_component_bind_ops); + ret = component_add(dev_priv->drm.dev, &i915_audio_component_bind_ops); if (ret < 0) { DRM_ERROR("failed to add audio component (%d)\n", ret); /* continue with reduced functionality */ @@ -821,6 +821,6 @@ void i915_audio_component_cleanup(struct drm_i915_private *dev_priv) if (!dev_priv->audio_component_registered) return; - component_del(dev_priv->dev->dev, &i915_audio_component_bind_ops); + component_del(dev_priv->drm.dev, &i915_audio_component_bind_ops); dev_priv->audio_component_registered = false; } diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index da5ed4a850b9..c6e69e4cfa83 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -1426,7 +1426,7 @@ static const struct vbt_header *find_vbt(void __iomem *bios, size_t size) int intel_bios_init(struct drm_i915_private *dev_priv) { - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; const struct vbt_header *vbt = dev_priv->opregion.vbt; const struct bdb_header *bdb; u8 __iomem *bios = NULL; diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index ea047cd46b71..c3b33a10c15c 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -412,7 +412,7 @@ static void csr_load_work_fn(struct work_struct *work) csr = &dev_priv->csr; ret = request_firmware(&fw, dev_priv->csr.fw_path, - &dev_priv->dev->pdev->dev); + &dev_priv->drm.pdev->dev); if (fw) dev_priv->csr.dmc_payload = parse_csr_fw(dev_priv, fw); @@ -426,7 +426,7 @@ static void csr_load_work_fn(struct work_struct *work) CSR_VERSION_MAJOR(csr->version), CSR_VERSION_MINOR(csr->version)); } else { - dev_notice(dev_priv->dev->dev, + dev_notice(dev_priv->drm.dev, "Failed to load DMC firmware" " [" FIRMWARE_URL "]," " disabling runtime power management.\n"); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4ff6e9304ef1..111b350d1d7e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1235,7 +1235,7 @@ void assert_fdi_rx_pll(struct drm_i915_private *dev_priv, void assert_panel_unlocked(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; i915_reg_t pp_reg; u32 val; enum pipe panel_pipe = PIPE_A; @@ -1277,7 +1277,7 @@ void assert_panel_unlocked(struct drm_i915_private *dev_priv, static void assert_cursor(struct drm_i915_private *dev_priv, enum pipe pipe, bool state) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; bool cur_state; if (IS_845G(dev) || IS_I865G(dev)) @@ -1339,7 +1339,7 @@ static void assert_plane(struct drm_i915_private *dev_priv, static void assert_planes_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; int i; /* Primary planes are fixed to pipes on gen4+ */ @@ -1365,7 +1365,7 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, static void assert_sprites_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; int sprite; if (INTEL_INFO(dev)->gen >= 9) { @@ -1830,7 +1830,7 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv, static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); i915_reg_t reg; @@ -1921,7 +1921,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv, static void ironlake_disable_pch_transcoder(struct drm_i915_private *dev_priv, enum pipe pipe) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; i915_reg_t reg; uint32_t val; @@ -3137,7 +3137,7 @@ static void intel_complete_page_flips(struct drm_i915_private *dev_priv) { struct intel_crtc *crtc; - for_each_intel_crtc(dev_priv->dev, crtc) + for_each_intel_crtc(&dev_priv->drm, crtc) intel_finish_page_flip_cs(dev_priv, crtc->pipe); } @@ -3171,12 +3171,12 @@ void intel_prepare_reset(struct drm_i915_private *dev_priv) if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) return; - drm_modeset_lock_all(dev_priv->dev); + drm_modeset_lock_all(&dev_priv->drm); /* * Disabling the crtcs gracefully seems nicer. Also the * g33 docs say we should at least disable all the planes. */ - intel_display_suspend(dev_priv->dev); + intel_display_suspend(&dev_priv->drm); } void intel_finish_reset(struct drm_i915_private *dev_priv) @@ -3203,7 +3203,7 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) * FIXME: Atomic will make this obsolete since we won't schedule * CS-based flips (which might get lost in gpu resets) any more. */ - intel_update_primary_planes(dev_priv->dev); + intel_update_primary_planes(&dev_priv->drm); return; } @@ -3214,18 +3214,18 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) intel_runtime_pm_disable_interrupts(dev_priv); intel_runtime_pm_enable_interrupts(dev_priv); - intel_modeset_init_hw(dev_priv->dev); + intel_modeset_init_hw(&dev_priv->drm); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display.hpd_irq_setup) dev_priv->display.hpd_irq_setup(dev_priv); spin_unlock_irq(&dev_priv->irq_lock); - intel_display_resume(dev_priv->dev); + intel_display_resume(&dev_priv->drm); intel_hpd_init(dev_priv); - drm_modeset_unlock_all(dev_priv->dev); + drm_modeset_unlock_all(&dev_priv->drm); } static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) @@ -5524,14 +5524,14 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, int cdclk) return; } - intel_update_cdclk(dev_priv->dev); + intel_update_cdclk(&dev_priv->drm); } static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv) { u32 cdctl, expected; - intel_update_cdclk(dev_priv->dev); + intel_update_cdclk(&dev_priv->drm); if (dev_priv->cdclk_pll.vco == 0 || dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref) @@ -5664,7 +5664,7 @@ void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv, int vco) dev_priv->skl_preferred_vco_freq = vco; if (changed) - intel_update_max_cdclk(dev_priv->dev); + intel_update_max_cdclk(&dev_priv->drm); } static void @@ -5758,7 +5758,7 @@ static bool skl_cdclk_wait_for_pcu_ready(struct drm_i915_private *dev_priv) static void skl_set_cdclk(struct drm_i915_private *dev_priv, int cdclk, int vco) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; u32 freq_select, pcu_ack; WARN_ON((cdclk == 24000) != (vco == 0)); @@ -5856,7 +5856,7 @@ static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv) if ((I915_READ(SWF_ILK(0x18)) & 0x00FFFFFF) == 0) goto sanitize; - intel_update_cdclk(dev_priv->dev); + intel_update_cdclk(&dev_priv->drm); /* Is PLL enabled and locked ? */ if (dev_priv->cdclk_pll.vco == 0 || dev_priv->cdclk_freq == dev_priv->cdclk_pll.ref) @@ -9488,7 +9488,7 @@ out: static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct intel_crtc *crtc; for_each_intel_crtc(dev, crtc) @@ -9522,7 +9522,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; if (IS_HASWELL(dev)) return I915_READ(D_COMP_HSW); @@ -9532,7 +9532,7 @@ static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv) static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; if (IS_HASWELL(dev)) { mutex_lock(&dev_priv->rps.hw_lock); @@ -9649,7 +9649,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) } intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); - intel_update_cdclk(dev_priv->dev); + intel_update_cdclk(&dev_priv->drm); } /* @@ -9677,7 +9677,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv) */ void hsw_enable_pc8(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; uint32_t val; DRM_DEBUG_KMS("Enabling package C8+\n"); @@ -9694,7 +9694,7 @@ void hsw_enable_pc8(struct drm_i915_private *dev_priv) void hsw_disable_pc8(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; uint32_t val; DRM_DEBUG_KMS("Disabling package C8+\n"); @@ -11142,7 +11142,7 @@ static bool pageflip_finished(struct intel_crtc *crtc, void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_flip_work *work; @@ -11169,7 +11169,7 @@ void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe) void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_flip_work *work; @@ -11628,7 +11628,7 @@ static bool __pageflip_stall_check_cs(struct drm_i915_private *dev_priv, void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_flip_work *work; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1083f5e2d45b..5e4d894968d6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -540,7 +540,7 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct intel_encoder *encoder; if (WARN_ON(!IS_VALLEYVIEW(dev) && !IS_CHERRYVIEW(dev) && @@ -2286,7 +2286,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp) * 2. Program DP PLL enable */ if (IS_GEN5(dev_priv)) - intel_wait_for_vblank_if_active(dev_priv->dev, !crtc->pipe); + intel_wait_for_vblank_if_active(&dev_priv->drm, !crtc->pipe); intel_dp->DP |= DP_PLL_ENABLE; @@ -3387,7 +3387,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) I915_WRITE(intel_dp->output_reg, DP); POSTING_READ(intel_dp->output_reg); - intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A); + intel_wait_for_vblank_if_active(&dev_priv->drm, PIPE_A); intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); } @@ -5147,9 +5147,9 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp) } if (dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) - intel_dp_set_drrs_state(dev_priv->dev, - intel_dp->attached_connector->panel. - fixed_mode->vrefresh); + intel_dp_set_drrs_state(&dev_priv->drm, + intel_dp->attached_connector->panel. + fixed_mode->vrefresh); dev_priv->drrs.dp = NULL; mutex_unlock(&dev_priv->drrs.mutex); @@ -5179,9 +5179,9 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work) goto unlock; if (dev_priv->drrs.refresh_rate_type != DRRS_LOW_RR) - intel_dp_set_drrs_state(dev_priv->dev, - intel_dp->attached_connector->panel. - downclock_mode->vrefresh); + intel_dp_set_drrs_state(&dev_priv->drm, + intel_dp->attached_connector->panel. + downclock_mode->vrefresh); unlock: mutex_unlock(&dev_priv->drrs.mutex); @@ -5223,9 +5223,9 @@ void intel_edp_drrs_invalidate(struct drm_device *dev, /* invalidate means busy screen hence upclock */ if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) - intel_dp_set_drrs_state(dev_priv->dev, - dev_priv->drrs.dp->attached_connector->panel. - fixed_mode->vrefresh); + intel_dp_set_drrs_state(&dev_priv->drm, + dev_priv->drrs.dp->attached_connector->panel. + fixed_mode->vrefresh); mutex_unlock(&dev_priv->drrs.mutex); } @@ -5268,9 +5268,9 @@ void intel_edp_drrs_flush(struct drm_device *dev, /* flush means busy screen hence upclock */ if (frontbuffer_bits && dev_priv->drrs.refresh_rate_type == DRRS_LOW_RR) - intel_dp_set_drrs_state(dev_priv->dev, - dev_priv->drrs.dp->attached_connector->panel. - fixed_mode->vrefresh); + intel_dp_set_drrs_state(&dev_priv->drm, + dev_priv->drrs.dp->attached_connector->panel. + fixed_mode->vrefresh); /* * flush also means no more activity hence schedule downclock, if all diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 8a4dac98b3d5..9098169b39c3 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -331,7 +331,7 @@ static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv, static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct intel_crtc *crtc; /* Make sure no transcoder isn't still depending on us. */ diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 067b6f518e48..6a7ad3ed1463 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -392,7 +392,7 @@ static void intel_fbc_work_fn(struct work_struct *__work) struct intel_fbc *fbc = &dev_priv->fbc; struct intel_fbc_work *work = &fbc->work; struct intel_crtc *crtc = fbc->crtc; - struct drm_vblank_crtc *vblank = &dev_priv->dev->vblank[crtc->pipe]; + struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[crtc->pipe]; if (drm_crtc_vblank_get(&crtc->base)) { DRM_ERROR("vblank not available for FBC on pipe %c\n", @@ -1210,7 +1210,7 @@ void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv) if (!no_fbc_on_multiple_pipes(dev_priv)) return; - for_each_intel_crtc(dev_priv->dev, crtc) + for_each_intel_crtc(&dev_priv->drm, crtc) if (intel_crtc_active(&crtc->base) && to_intel_plane_state(crtc->base.primary->state)->visible) dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe); diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index 5205afd69ff6..86b00c6db1a6 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -693,9 +693,9 @@ out: static void intel_fbdev_suspend_worker(struct work_struct *work) { - intel_fbdev_set_suspend(container_of(work, - struct drm_i915_private, - fbdev_suspend_work)->dev, + intel_fbdev_set_suspend(&container_of(work, + struct drm_i915_private, + fbdev_suspend_work)->drm, FBINFO_STATE_RUNNING, true); } diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 3fca95501890..2aa744081f09 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -289,7 +289,7 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, bool ret; spin_lock_irqsave(&dev_priv->irq_lock, flags); - ret = __intel_set_cpu_fifo_underrun_reporting(dev_priv->dev, pipe, + ret = __intel_set_cpu_fifo_underrun_reporting(&dev_priv->drm, pipe, enable); spin_unlock_irqrestore(&dev_priv->irq_lock, flags); @@ -334,10 +334,12 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, intel_crtc->pch_fifo_underrun_disabled = !enable; if (HAS_PCH_IBX(dev_priv)) - ibx_set_fifo_underrun_reporting(dev_priv->dev, pch_transcoder, + ibx_set_fifo_underrun_reporting(&dev_priv->drm, + pch_transcoder, enable); else - cpt_set_fifo_underrun_reporting(dev_priv->dev, pch_transcoder, + cpt_set_fifo_underrun_reporting(&dev_priv->drm, + pch_transcoder, enable, old); spin_unlock_irqrestore(&dev_priv->irq_lock, flags); @@ -405,7 +407,7 @@ void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv) spin_lock_irq(&dev_priv->irq_lock); - for_each_intel_crtc(dev_priv->dev, crtc) { + for_each_intel_crtc(&dev_priv->drm, crtc) { if (crtc->cpu_fifo_underrun_disabled) continue; @@ -432,7 +434,7 @@ void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv) spin_lock_irq(&dev_priv->irq_lock); - for_each_intel_crtc(dev_priv->dev, crtc) { + for_each_intel_crtc(&dev_priv->drm, crtc) { if (crtc->pch_fifo_underrun_disabled) continue; diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index d925e2daeb24..605c69658d2c 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -314,7 +314,7 @@ static u32 guc_wopcm_size(struct drm_i915_private *dev_priv) static int guc_ucode_xfer(struct drm_i915_private *dev_priv) { struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; int ret; ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 4f4e4b535683..e94244266b19 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1154,7 +1154,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) I915_WRITE(intel_hdmi->hdmi_reg, temp); POSTING_READ(intel_hdmi->hdmi_reg); - intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A); + intel_wait_for_vblank_if_active(&dev_priv->drm, PIPE_A); intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); } diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index 38eeca7a6e72..51434ec871f2 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -144,7 +144,7 @@ static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv, static void intel_hpd_irq_storm_disable(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_mode_config *mode_config = &dev->mode_config; struct intel_connector *intel_connector; struct intel_encoder *intel_encoder; @@ -191,7 +191,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), hotplug.reenable_work.work); - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_mode_config *mode_config = &dev->mode_config; int i; @@ -302,7 +302,7 @@ static void i915_hotplug_work_func(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, struct drm_i915_private, hotplug.hotplug_work); - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_mode_config *mode_config = &dev->mode_config; struct intel_connector *intel_connector; struct intel_encoder *intel_encoder; @@ -455,7 +455,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, */ void intel_hpd_init(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; int i; diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 3c6f338866da..1f266d7df2ec 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -138,7 +138,7 @@ static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable) static u32 get_reserved(struct intel_gmbus *bus) { struct drm_i915_private *dev_priv = bus->dev_priv; - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; u32 reserved = 0; /* On most chips, these bits must be preserved in software. */ @@ -212,7 +212,7 @@ intel_gpio_pre_xfer(struct i2c_adapter *adapter) adapter); struct drm_i915_private *dev_priv = bus->dev_priv; - intel_i2c_reset(dev_priv->dev); + intel_i2c_reset(&dev_priv->drm); intel_i2c_quirk_set(dev_priv, true); set_data(bus, 1); set_clock(bus, 1); @@ -688,7 +688,7 @@ int intel_setup_gmbus(struct drm_device *dev) goto err; } - intel_i2c_reset(dev_priv->dev); + intel_i2c_reset(&dev_priv->drm); return 0; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 676b53200e94..d47d1a0dbb91 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -899,7 +899,7 @@ void intel_execlists_cancel_requests(struct intel_engine_cs *engine) struct drm_i915_gem_request *req, *tmp; LIST_HEAD(cancel_list); - WARN_ON(!mutex_is_locked(&engine->i915->dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&engine->i915->drm.struct_mutex)); spin_lock_bh(&engine->execlist_lock); list_replace_init(&engine->execlist_queue, &cancel_list); @@ -961,7 +961,7 @@ static int intel_lr_context_pin(struct i915_gem_context *ctx, u32 *lrc_reg_state; int ret; - lockdep_assert_held(&ctx->i915->dev->struct_mutex); + lockdep_assert_held(&ctx->i915->drm.struct_mutex); if (ce->pin_count++) return 0; @@ -1011,7 +1011,7 @@ void intel_lr_context_unpin(struct i915_gem_context *ctx, { struct intel_context *ce = &ctx->engine[engine->id]; - lockdep_assert_held(&ctx->i915->dev->struct_mutex); + lockdep_assert_held(&ctx->i915->drm.struct_mutex); GEM_BUG_ON(ce->pin_count == 0); if (--ce->pin_count) @@ -1353,8 +1353,8 @@ static int lrc_setup_wa_ctx_obj(struct intel_engine_cs *engine, u32 size) { int ret; - engine->wa_ctx.obj = i915_gem_object_create(engine->i915->dev, - PAGE_ALIGN(size)); + engine->wa_ctx.obj = i915_gem_object_create(&engine->i915->drm, + PAGE_ALIGN(size)); if (IS_ERR(engine->wa_ctx.obj)) { DRM_DEBUG_DRIVER("alloc LRC WA ctx backing obj failed.\n"); ret = PTR_ERR(engine->wa_ctx.obj); @@ -2154,7 +2154,7 @@ logical_ring_setup(struct drm_i915_private *dev_priv, enum intel_engine_id id) logical_ring_default_irqs(engine, info->irq_shift); intel_engine_init_hangcheck(engine); - i915_gem_batch_pool_init(dev_priv->dev, &engine->batch_pool); + i915_gem_batch_pool_init(&dev_priv->drm, &engine->batch_pool); return engine; } @@ -2486,7 +2486,7 @@ static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, /* One extra page as the sharing data between driver and GuC */ context_size += PAGE_SIZE * LRC_PPHWSP_PN; - ctx_obj = i915_gem_object_create(ctx->i915->dev, context_size); + ctx_obj = i915_gem_object_create(&ctx->i915->drm, context_size); if (IS_ERR(ctx_obj)) { DRM_DEBUG_DRIVER("Alloc LRC backing obj failed.\n"); return PTR_ERR(ctx_obj); diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 82e687dd09c3..87a9bd040106 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -261,7 +261,7 @@ static int swsci(struct drm_i915_private *dev_priv, u32 function, u32 parm, u32 *parm_out) { struct opregion_swsci *swsci = dev_priv->opregion.swsci; - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; u32 main_function, sub_function, scic; u16 swsci_val; u32 dslp; @@ -435,7 +435,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp) { struct intel_connector *connector; struct opregion_asle *asle = dev_priv->opregion.asle; - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); @@ -718,7 +718,7 @@ static u32 acpi_display_type(struct drm_connector *connector) static void intel_didl_outputs(struct drm_i915_private *dev_priv) { struct intel_opregion *opregion = &dev_priv->opregion; - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; struct drm_connector *connector; acpi_handle handle; struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; @@ -782,7 +782,8 @@ end: blind_set: i = 0; - list_for_each_entry(connector, &dev_priv->dev->mode_config.connector_list, head) { + list_for_each_entry(connector, + &dev_priv->drm.mode_config.connector_list, head) { int display_type = acpi_display_type(connector); if (i >= max_outputs) { @@ -954,7 +955,7 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = { int intel_opregion_setup(struct drm_i915_private *dev_priv) { struct intel_opregion *opregion = &dev_priv->opregion; - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; u32 asls, mboxes; char buf[sizeof(OPREGION_SIGNATURE)]; int err = 0; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index e9887d9321a3..3212d8806b5a 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -409,7 +409,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) struct intel_engine_cs *engine = &dev_priv->engine[RCS]; int ret; - lockdep_assert_held(&dev_priv->dev->struct_mutex); + lockdep_assert_held(&dev_priv->drm.struct_mutex); /* Only wait if there is actually an old frame to release to * guarantee forward progress. @@ -741,8 +741,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, u32 swidth, swidthsw, sheight, ostride; enum pipe pipe = overlay->crtc->pipe; - lockdep_assert_held(&dev_priv->dev->struct_mutex); - WARN_ON(!drm_modeset_is_locked(&dev_priv->dev->mode_config.connection_mutex)); + lockdep_assert_held(&dev_priv->drm.struct_mutex); + WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); ret = intel_overlay_release_old_vid(overlay); if (ret != 0) @@ -836,7 +836,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, overlay->old_vid_bo = overlay->vid_bo; overlay->vid_bo = new_bo; - intel_frontbuffer_flip(dev_priv->dev, INTEL_FRONTBUFFER_OVERLAY(pipe)); + intel_frontbuffer_flip(&dev_priv->drm, + INTEL_FRONTBUFFER_OVERLAY(pipe)); return 0; @@ -851,8 +852,8 @@ int intel_overlay_switch_off(struct intel_overlay *overlay) struct overlay_registers __iomem *regs; int ret; - lockdep_assert_held(&dev_priv->dev->struct_mutex); - WARN_ON(!drm_modeset_is_locked(&dev_priv->dev->mode_config.connection_mutex)); + lockdep_assert_held(&dev_priv->drm.struct_mutex); + WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); ret = intel_overlay_recover_from_interrupt(overlay); if (ret != 0) @@ -1379,7 +1380,7 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) if (!overlay) return; - mutex_lock(&dev_priv->dev->struct_mutex); + mutex_lock(&dev_priv->drm.struct_mutex); if (WARN_ON(dev_priv->overlay)) goto out_free; @@ -1387,9 +1388,10 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) reg_bo = NULL; if (!OVERLAY_NEEDS_PHYSICAL(dev_priv)) - reg_bo = i915_gem_object_create_stolen(dev_priv->dev, PAGE_SIZE); + reg_bo = i915_gem_object_create_stolen(&dev_priv->drm, + PAGE_SIZE); if (reg_bo == NULL) - reg_bo = i915_gem_object_create(dev_priv->dev, PAGE_SIZE); + reg_bo = i915_gem_object_create(&dev_priv->drm, PAGE_SIZE); if (IS_ERR(reg_bo)) goto out_free; overlay->reg_bo = reg_bo; @@ -1434,7 +1436,7 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) intel_overlay_unmap_regs(overlay, regs); dev_priv->overlay = overlay; - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); DRM_INFO("initialized overlay support\n"); return; @@ -1444,7 +1446,7 @@ out_unpin_bo: out_free_bo: drm_gem_object_unreference(®_bo->base); out_free: - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); kfree(overlay); return; } diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index a8b473350597..295f0ddca718 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -504,7 +504,7 @@ static u32 i9xx_get_backlight(struct intel_connector *connector) if (panel->backlight.combination_mode) { u8 lbpc; - pci_read_config_byte(dev_priv->dev->pdev, LBPC, &lbpc); + pci_read_config_byte(dev_priv->drm.pdev, LBPC, &lbpc); val *= lbpc; } @@ -592,7 +592,7 @@ static void i9xx_set_backlight(struct intel_connector *connector, u32 level) lbpc = level * 0xfe / panel->backlight.max + 1; level /= lbpc; - pci_write_config_byte(dev_priv->dev->pdev, LBPC, lbpc); + pci_write_config_byte(dev_priv->drm.pdev, LBPC, lbpc); } if (IS_GEN4(dev_priv)) { @@ -822,7 +822,7 @@ void intel_panel_disable_backlight(struct intel_connector *connector) * backlight. This will leave the backlight on unnecessarily when * another client is not activated. */ - if (dev_priv->dev->switch_power_state == DRM_SWITCH_POWER_CHANGING) { + if (dev_priv->drm.switch_power_state == DRM_SWITCH_POWER_CHANGING) { DRM_DEBUG_DRIVER("Skipping backlight disable on vga switch\n"); return; } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0560b7c90244..5a8ee0c76593 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -319,7 +319,7 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; u32 val; if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { @@ -2236,7 +2236,7 @@ static void intel_print_wm_latency(struct drm_device *dev, static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, uint16_t wm[5], uint16_t min) { - int level, max_level = ilk_wm_max_level(dev_priv->dev); + int level, max_level = ilk_wm_max_level(&dev_priv->drm); if (wm[0] >= min) return false; @@ -2765,7 +2765,7 @@ static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv, static void ilk_write_wm_values(struct drm_i915_private *dev_priv, struct ilk_wm_values *results) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct ilk_wm_values *previous = &dev_priv->wm.hw; unsigned int dirty; uint32_t val; @@ -3498,7 +3498,6 @@ skl_compute_wm_level(const struct drm_i915_private *dev_priv, int level, struct skl_wm_level *result) { - struct drm_device *dev = dev_priv->dev; struct drm_atomic_state *state = cstate->base.state; struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); struct drm_plane *plane; @@ -3514,7 +3513,9 @@ skl_compute_wm_level(const struct drm_i915_private *dev_priv, */ memset(result, 0, sizeof(*result)); - for_each_intel_plane_mask(dev, intel_plane, cstate->base.plane_mask) { + for_each_intel_plane_mask(&dev_priv->drm, + intel_plane, + cstate->base.plane_mask) { int i = skl_wm_plane_id(intel_plane); plane = &intel_plane->base; @@ -3682,7 +3683,7 @@ static void skl_ddb_entry_write(struct drm_i915_private *dev_priv, static void skl_write_wm_values(struct drm_i915_private *dev_priv, const struct skl_wm_values *new) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct intel_crtc *crtc; for_each_intel_crtc(dev, crtc) { @@ -3779,7 +3780,7 @@ skl_ddb_allocation_included(const struct skl_ddb_allocation *old, static void skl_flush_wm_values(struct drm_i915_private *dev_priv, struct skl_wm_values *new_values) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct skl_ddb_allocation *cur_ddb, *new_ddb; bool reallocated[I915_MAX_PIPES] = {}; struct intel_crtc *crtc; @@ -4056,7 +4057,7 @@ static void ilk_compute_wm_config(struct drm_device *dev, static void ilk_program_watermarks(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; struct intel_wm_config config = {}; @@ -5699,7 +5700,7 @@ static void valleyview_setup_pctx(struct drm_i915_private *dev_priv) u32 pcbr; int pctx_size = 24*1024; - mutex_lock(&dev_priv->dev->struct_mutex); + mutex_lock(&dev_priv->drm.struct_mutex); pcbr = I915_READ(VLV_PCBR); if (pcbr) { @@ -5707,7 +5708,7 @@ static void valleyview_setup_pctx(struct drm_i915_private *dev_priv) int pcbr_offset; pcbr_offset = (pcbr & (~4095)) - dev_priv->mm.stolen_base; - pctx = i915_gem_object_create_stolen_for_preallocated(dev_priv->dev, + pctx = i915_gem_object_create_stolen_for_preallocated(&dev_priv->drm, pcbr_offset, I915_GTT_OFFSET_NONE, pctx_size); @@ -5724,7 +5725,7 @@ static void valleyview_setup_pctx(struct drm_i915_private *dev_priv) * overlap with other ranges, such as the frame buffer, protected * memory, or any other relevant ranges. */ - pctx = i915_gem_object_create_stolen(dev_priv->dev, pctx_size); + pctx = i915_gem_object_create_stolen(&dev_priv->drm, pctx_size); if (!pctx) { DRM_DEBUG("not enough stolen space for PCTX, disabling\n"); goto out; @@ -5736,7 +5737,7 @@ static void valleyview_setup_pctx(struct drm_i915_private *dev_priv) out: DRM_DEBUG_DRIVER("PCBR: 0x%08x\n", I915_READ(VLV_PCBR)); dev_priv->vlv_pctx = pctx; - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); } static void valleyview_cleanup_pctx(struct drm_i915_private *dev_priv) @@ -6680,9 +6681,9 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) if (IS_IRONLAKE_M(dev_priv)) { ironlake_enable_drps(dev_priv); - mutex_lock(&dev_priv->dev->struct_mutex); + mutex_lock(&dev_priv->drm.struct_mutex); intel_init_emon(dev_priv); - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->drm.struct_mutex); } else if (INTEL_INFO(dev_priv)->gen >= 6) { /* * PCU communication is slow and this doesn't need to be diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 428ed62dc5de..61e00bf9e87f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -657,9 +657,9 @@ int intel_init_pipe_control(struct intel_engine_cs *engine, int size) WARN_ON(engine->scratch.obj); - obj = i915_gem_object_create_stolen(engine->i915->dev, size); + obj = i915_gem_object_create_stolen(&engine->i915->drm, size); if (!obj) - obj = i915_gem_object_create(engine->i915->dev, size); + obj = i915_gem_object_create(&engine->i915->drm, size); if (IS_ERR(obj)) { DRM_ERROR("Failed to allocate scratch page\n"); ret = PTR_ERR(obj); @@ -1888,7 +1888,7 @@ static void cleanup_phys_status_page(struct intel_engine_cs *engine) if (!dev_priv->status_page_dmah) return; - drm_pci_free(dev_priv->dev, dev_priv->status_page_dmah); + drm_pci_free(&dev_priv->drm, dev_priv->status_page_dmah); engine->status_page.page_addr = NULL; } @@ -1914,7 +1914,7 @@ static int init_status_page(struct intel_engine_cs *engine) unsigned flags; int ret; - obj = i915_gem_object_create(engine->i915->dev, 4096); + obj = i915_gem_object_create(&engine->i915->drm, 4096); if (IS_ERR(obj)) { DRM_ERROR("Failed to allocate status page\n"); return PTR_ERR(obj); @@ -1963,7 +1963,7 @@ static int init_phys_status_page(struct intel_engine_cs *engine) if (!dev_priv->status_page_dmah) { dev_priv->status_page_dmah = - drm_pci_alloc(dev_priv->dev, PAGE_SIZE, PAGE_SIZE); + drm_pci_alloc(&dev_priv->drm, PAGE_SIZE, PAGE_SIZE); if (!dev_priv->status_page_dmah) return -ENOMEM; } @@ -2096,7 +2096,7 @@ intel_engine_create_ringbuffer(struct intel_engine_cs *engine, int size) ring->last_retired_head = -1; intel_ring_update_space(ring); - ret = intel_alloc_ringbuffer_obj(engine->i915->dev, ring); + ret = intel_alloc_ringbuffer_obj(&engine->i915->drm, ring); if (ret) { DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s: %d\n", engine->name, ret); @@ -2122,7 +2122,7 @@ static int intel_ring_context_pin(struct i915_gem_context *ctx, struct intel_context *ce = &ctx->engine[engine->id]; int ret; - lockdep_assert_held(&ctx->i915->dev->struct_mutex); + lockdep_assert_held(&ctx->i915->drm.struct_mutex); if (ce->pin_count++) return 0; @@ -2156,7 +2156,7 @@ static void intel_ring_context_unpin(struct i915_gem_context *ctx, { struct intel_context *ce = &ctx->engine[engine->id]; - lockdep_assert_held(&ctx->i915->dev->struct_mutex); + lockdep_assert_held(&ctx->i915->drm.struct_mutex); if (--ce->pin_count) return; @@ -2696,7 +2696,7 @@ static void intel_ring_init_semaphores(struct drm_i915_private *dev_priv, return; if (INTEL_GEN(dev_priv) >= 8 && !dev_priv->semaphore_obj) { - obj = i915_gem_object_create(dev_priv->dev, 4096); + obj = i915_gem_object_create(&dev_priv->drm, 4096); if (IS_ERR(obj)) { DRM_ERROR("Failed to allocate semaphore bo. Disabling semaphores\n"); i915.semaphores = 0; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 7cbba42f0ab4..6b78295f53db 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -287,7 +287,7 @@ void intel_display_set_init_power(struct drm_i915_private *dev_priv, */ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; /* * After we re-enable the power well, if we touch VGA register 0x3d5 @@ -318,7 +318,7 @@ static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv) static void skl_power_well_post_enable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; /* * After we re-enable the power well, if we touch VGA register 0x3d5 @@ -930,7 +930,7 @@ static void gen9_dc_off_power_well_enable(struct drm_i915_private *dev_priv, gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); WARN_ON(dev_priv->cdclk_freq != - dev_priv->display.get_display_clock_speed(dev_priv->dev)); + dev_priv->display.get_display_clock_speed(&dev_priv->drm)); gen9_assert_dbuf_enabled(dev_priv); @@ -1088,7 +1088,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv) * * CHV DPLL B/C have some issues if VGA mode is enabled. */ - for_each_pipe(dev_priv->dev, pipe) { + for_each_pipe(&dev_priv->drm, pipe) { u32 val = I915_READ(DPLL(pipe)); val |= DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS; @@ -1113,7 +1113,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv) intel_hpd_init(dev_priv); - i915_redisable_vga_power_on(dev_priv->dev); + i915_redisable_vga_power_on(&dev_priv->drm); } static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv) @@ -1123,7 +1123,7 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv) spin_unlock_irq(&dev_priv->irq_lock); /* make sure we're done processing display irqs */ - synchronize_irq(dev_priv->dev->irq); + synchronize_irq(dev_priv->drm.irq); intel_power_sequencer_reset(dev_priv); } @@ -2275,7 +2275,7 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) */ void intel_power_domains_fini(struct drm_i915_private *dev_priv) { - struct device *device = &dev_priv->dev->pdev->dev; + struct device *device = &dev_priv->drm.pdev->dev; /* * The i915.ko module is still not prepared to be loaded when @@ -2576,7 +2576,7 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv) */ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct i915_power_domains *power_domains = &dev_priv->power_domains; power_domains->initializing = true; @@ -2638,7 +2638,7 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv) */ void intel_runtime_pm_get(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct device *device = &dev->pdev->dev; pm_runtime_get_sync(device); @@ -2659,7 +2659,7 @@ void intel_runtime_pm_get(struct drm_i915_private *dev_priv) */ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct device *device = &dev->pdev->dev; if (IS_ENABLED(CONFIG_PM)) { @@ -2701,7 +2701,7 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv) */ void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct device *device = &dev->pdev->dev; assert_rpm_wakelock_held(dev_priv); @@ -2720,7 +2720,7 @@ void intel_runtime_pm_get_noresume(struct drm_i915_private *dev_priv) */ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct device *device = &dev->pdev->dev; assert_rpm_wakelock_held(dev_priv); @@ -2743,7 +2743,7 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) */ void intel_runtime_pm_enable(struct drm_i915_private *dev_priv) { - struct drm_device *dev = dev_priv->dev; + struct drm_device *dev = &dev_priv->drm; struct device *device = &dev->pdev->dev; pm_runtime_set_autosuspend_delay(device, 10000); /* 10s */ diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 321121e8fa2c..e378f35365a2 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1471,7 +1471,7 @@ static void intel_disable_sdvo(struct intel_encoder *encoder) temp &= ~SDVO_ENABLE; intel_sdvo_write_sdvox(intel_sdvo, temp); - intel_wait_for_vblank_if_active(dev_priv->dev, PIPE_A); + intel_wait_for_vblank_if_active(&dev_priv->drm, PIPE_A); intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true); intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true); } diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 1d65209c0998..ff80a81b1a84 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1471,7 +1471,7 @@ static int i915_reset_complete(struct pci_dev *pdev) static int i915_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) { - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; /* assert reset for at least 20 usec */ pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE); @@ -1490,14 +1490,14 @@ static int g4x_reset_complete(struct pci_dev *pdev) static int g33_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) { - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; pci_write_config_byte(pdev, I915_GDRST, GRDOM_RESET_ENABLE); return wait_for(g4x_reset_complete(pdev), 500); } static int g4x_do_reset(struct drm_i915_private *dev_priv, unsigned engine_mask) { - struct pci_dev *pdev = dev_priv->dev->pdev; + struct pci_dev *pdev = dev_priv->drm.pdev; int ret; pci_write_config_byte(pdev, I915_GDRST, -- cgit v1.2.3 From 04171313cb25311acf82279284d722fed7b70d53 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 6 Jul 2016 12:39:00 +0100 Subject: drm/i915: Always double check for a missed interrupt for new bottom halves After assigning ourselves as the new bottom-half, we must perform a cursory check to prevent a missed interrupt. Either we miss the interrupt whilst programming the hardware, or if there was a previous waiter (for a later seqno) they may be woken instead of us (due to the inherent race in the unlocked read of b->tasklet in the irq handler) and so we miss the wake up. Spotted-by: Tvrtko Ursulin Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96806 Fixes: 688e6c725816 ("drm/i915: Slaughter the thundering... herd") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467805142-22219-1-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_breadcrumbs.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 009d6e121767..6fcbb52e50fb 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -65,7 +65,7 @@ static void irq_disable(struct intel_engine_cs *engine) engine->irq_posted = false; } -static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) +static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) { struct intel_engine_cs *engine = container_of(b, struct intel_engine_cs, breadcrumbs); @@ -73,7 +73,7 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) assert_spin_locked(&b->lock); if (b->rpm_wakelock) - return false; + return; /* Since we are waiting on a request, the GPU should be busy * and should have its own rpm reference. For completeness, @@ -93,8 +93,6 @@ static bool __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) if (!b->irq_enabled || test_bit(engine->id, &i915->gpu_error.missed_irq_rings)) mod_timer(&b->fake_irq, jiffies + 1); - - return engine->irq_posted; } static void __intel_breadcrumbs_disable_irq(struct intel_breadcrumbs *b) @@ -233,7 +231,15 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, GEM_BUG_ON(rb_first(&b->waiters) != &wait->node); b->first_wait = wait; smp_store_mb(b->tasklet, wait->tsk); - first = __intel_breadcrumbs_enable_irq(b); + /* After assigning ourselves as the new bottom-half, we must + * perform a cursory check to prevent a missed interrupt. + * Either we miss the interrupt whilst programming the hardware, + * or if there was a previous waiter (for a later seqno) they + * may be woken instead of us (due to the inherent race + * in the unlocked read of b->tasklet in the irq handler) and + * so we miss the wake up. + */ + __intel_breadcrumbs_enable_irq(b); } GEM_BUG_ON(!b->tasklet); GEM_BUG_ON(!b->first_wait); -- cgit v1.2.3 From 99fe4a5f7383559ee120492124365e708a587130 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 6 Jul 2016 12:39:01 +0100 Subject: drm/i915: Wake up the bottom-half if we steal their interrupt Following on from the scenario Tvrtko envisioned to explain a hard-to-hit race with multiple first waiters, we could also then race in the __i915_request_irq_complete() and the bottom-half may miss the vital irq-seqno barrier and so go to sleep not noticing their seqno is complete. v2: unlock, not double lock the rcu_read_lock. Fixes: 3d5564e91025 ("drm/i915: Only apply one barrier after...") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467805142-22219-2-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c269e0ad4057..11e9769411e9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3998,7 +3998,10 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) * is woken. */ if (engine->irq_seqno_barrier && + READ_ONCE(engine->breadcrumbs.tasklet) == current && cmpxchg_relaxed(&engine->irq_posted, 1, 0)) { + struct task_struct *tsk; + /* The ordering of irq_posted versus applying the barrier * is crucial. The clearing of the current irq_posted must * be visible before we perform the barrier operation, @@ -4012,6 +4015,25 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) * seqno update. */ engine->irq_seqno_barrier(engine); + + /* If we consume the irq, but we are no longer the bottom-half, + * the real bottom-half may not have serialised their own + * seqno check with the irq-barrier (i.e. may have inspected + * the seqno before we believe it coherent since they see + * irq_posted == false but we are still running). + */ + rcu_read_lock(); + tsk = READ_ONCE(engine->breadcrumbs.tasklet); + if (tsk && tsk != current) + /* Note that if the bottom-half is changed as we + * are sending the wake-up, the new bottom-half will + * be woken by whomever made the change. We only have + * to worry about when we steal the irq-posted for + * ourself. + */ + wake_up_process(tsk); + rcu_read_unlock(); + if (i915_gem_request_completed(req)) return true; } -- cgit v1.2.3 From aca34b6e1ca909ba15f6c1c1dc89bea8f455403f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 6 Jul 2016 12:39:02 +0100 Subject: drm/i915: Group the irq breadcrumb variables into the same cacheline As we inspect both the tasklet (to check for an active bottom-half) and set the irq-posted flag at the same time (both in the interrupt handler and then in the bottom-halt), group those two together into the same cacheline. (Not having total control over placement of the struct means we can't guarantee the cacheline boundary, we need to align the kmalloc and then each struct, but the grouping should help.) v2: Try a couple of different names for the state touched by the user interrupt handler. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467805142-22219-3-git-send-email-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 8 ++++---- drivers/gpu/drm/i915/i915_drv.h | 6 +++--- drivers/gpu/drm/i915/i915_irq.c | 12 ++++++------ drivers/gpu/drm/i915/intel_breadcrumbs.c | 28 ++++++++++++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 18 ++++++++++-------- 5 files changed, 37 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a59e0caeda64..3d05cae0e92d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -793,8 +793,8 @@ static void i915_ring_seqno_info(struct seq_file *m, seq_printf(m, "Current sequence (%s): %x\n", engine->name, intel_engine_get_seqno(engine)); - seq_printf(m, "Current user interrupts (%s): %x\n", - engine->name, READ_ONCE(engine->user_interrupts)); + seq_printf(m, "Current user interrupts (%s): %lx\n", + engine->name, READ_ONCE(engine->breadcrumbs.irq_wakeups)); spin_lock(&b->lock); for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { @@ -1442,9 +1442,9 @@ static int i915_hangcheck_info(struct seq_file *m, void *unused) engine->last_submitted_seqno); seq_printf(m, "\twaiters? %d\n", intel_engine_has_waiter(engine)); - seq_printf(m, "\tuser interrupts = %x [current %x]\n", + seq_printf(m, "\tuser interrupts = %lx [current %lx]\n", engine->hangcheck.user_interrupts, - READ_ONCE(engine->user_interrupts)); + READ_ONCE(engine->breadcrumbs.irq_wakeups)); seq_printf(m, "\tACTHD = 0x%08llx [current 0x%08llx]\n", (long long)engine->hangcheck.acthd, (long long)acthd[id]); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 11e9769411e9..d2c60992a508 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3998,8 +3998,8 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) * is woken. */ if (engine->irq_seqno_barrier && - READ_ONCE(engine->breadcrumbs.tasklet) == current && - cmpxchg_relaxed(&engine->irq_posted, 1, 0)) { + READ_ONCE(engine->breadcrumbs.irq_seqno_bh) == current && + cmpxchg_relaxed(&engine->breadcrumbs.irq_posted, 1, 0)) { struct task_struct *tsk; /* The ordering of irq_posted versus applying the barrier @@ -4023,7 +4023,7 @@ static inline bool __i915_request_irq_complete(struct drm_i915_gem_request *req) * irq_posted == false but we are still running). */ rcu_read_lock(); - tsk = READ_ONCE(engine->breadcrumbs.tasklet); + tsk = READ_ONCE(engine->breadcrumbs.irq_seqno_bh); if (tsk && tsk != current) /* Note that if the bottom-half is changed as we * are sending the wake-up, the new bottom-half will diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b77d808b71cd..a69a5fc75bd6 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -977,10 +977,10 @@ static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv) static void notify_ring(struct intel_engine_cs *engine) { - smp_store_mb(engine->irq_posted, true); + smp_store_mb(engine->breadcrumbs.irq_posted, true); if (intel_engine_wakeup(engine)) { trace_i915_gem_request_notify(engine); - engine->user_interrupts++; + engine->breadcrumbs.irq_wakeups++; } } @@ -3054,12 +3054,12 @@ ring_stuck(struct intel_engine_cs *engine, u64 acthd) return HANGCHECK_HUNG; } -static unsigned kick_waiters(struct intel_engine_cs *engine) +static unsigned long kick_waiters(struct intel_engine_cs *engine) { struct drm_i915_private *i915 = engine->i915; - unsigned user_interrupts = READ_ONCE(engine->user_interrupts); + unsigned long irq_count = READ_ONCE(engine->breadcrumbs.irq_wakeups); - if (engine->hangcheck.user_interrupts == user_interrupts && + if (engine->hangcheck.user_interrupts == irq_count && !test_and_set_bit(engine->id, &i915->gpu_error.missed_irq_rings)) { if (!test_bit(engine->id, &i915->gpu_error.test_irq_rings)) DRM_ERROR("Hangcheck timer elapsed... %s idle\n", @@ -3068,7 +3068,7 @@ static unsigned kick_waiters(struct intel_engine_cs *engine) intel_engine_enable_fake_irq(engine); } - return user_interrupts; + return irq_count; } /* * This is called when the chip hasn't reported back with completed diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 6fcbb52e50fb..d89b2c963618 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -49,7 +49,7 @@ static void irq_enable(struct intel_engine_cs *engine) * we still need to force the barrier before reading the seqno, * just in case. */ - engine->irq_posted = true; + engine->breadcrumbs.irq_posted = true; spin_lock_irq(&engine->i915->irq_lock); engine->irq_enable(engine); @@ -62,7 +62,7 @@ static void irq_disable(struct intel_engine_cs *engine) engine->irq_disable(engine); spin_unlock_irq(&engine->i915->irq_lock); - engine->irq_posted = false; + engine->breadcrumbs.irq_posted = false; } static void __intel_breadcrumbs_enable_irq(struct intel_breadcrumbs *b) @@ -195,7 +195,7 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, } rb_link_node(&wait->node, parent, p); rb_insert_color(&wait->node, &b->waiters); - GEM_BUG_ON(!first && !b->tasklet); + GEM_BUG_ON(!first && !b->irq_seqno_bh); if (completed) { struct rb_node *next = rb_next(completed); @@ -204,7 +204,7 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, if (next && next != &wait->node) { GEM_BUG_ON(first); b->first_wait = to_wait(next); - smp_store_mb(b->tasklet, b->first_wait->tsk); + smp_store_mb(b->irq_seqno_bh, b->first_wait->tsk); /* As there is a delay between reading the current * seqno, processing the completed tasks and selecting * the next waiter, we may have missed the interrupt @@ -216,7 +216,7 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, * in case the seqno passed. */ __intel_breadcrumbs_enable_irq(b); - if (READ_ONCE(engine->irq_posted)) + if (READ_ONCE(b->irq_posted)) wake_up_process(to_wait(next)->tsk); } @@ -230,18 +230,18 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine, if (first) { GEM_BUG_ON(rb_first(&b->waiters) != &wait->node); b->first_wait = wait; - smp_store_mb(b->tasklet, wait->tsk); + smp_store_mb(b->irq_seqno_bh, wait->tsk); /* After assigning ourselves as the new bottom-half, we must * perform a cursory check to prevent a missed interrupt. * Either we miss the interrupt whilst programming the hardware, * or if there was a previous waiter (for a later seqno) they * may be woken instead of us (due to the inherent race - * in the unlocked read of b->tasklet in the irq handler) and - * so we miss the wake up. + * in the unlocked read of b->irq_seqno_bh in the irq handler) + * and so we miss the wake up. */ __intel_breadcrumbs_enable_irq(b); } - GEM_BUG_ON(!b->tasklet); + GEM_BUG_ON(!b->irq_seqno_bh); GEM_BUG_ON(!b->first_wait); GEM_BUG_ON(rb_first(&b->waiters) != &b->first_wait->node); @@ -301,7 +301,7 @@ void intel_engine_remove_wait(struct intel_engine_cs *engine, const int priority = wakeup_priority(b, wait->tsk); struct rb_node *next; - GEM_BUG_ON(b->tasklet != wait->tsk); + GEM_BUG_ON(b->irq_seqno_bh != wait->tsk); /* We are the current bottom-half. Find the next candidate, * the first waiter in the queue on the remaining oldest @@ -344,13 +344,13 @@ void intel_engine_remove_wait(struct intel_engine_cs *engine, * exception rather than a seqno completion. */ b->first_wait = to_wait(next); - smp_store_mb(b->tasklet, b->first_wait->tsk); + smp_store_mb(b->irq_seqno_bh, b->first_wait->tsk); if (b->first_wait->seqno != wait->seqno) __intel_breadcrumbs_enable_irq(b); - wake_up_process(b->tasklet); + wake_up_process(b->irq_seqno_bh); } else { b->first_wait = NULL; - WRITE_ONCE(b->tasklet, NULL); + WRITE_ONCE(b->irq_seqno_bh, NULL); __intel_breadcrumbs_disable_irq(b); } } else { @@ -364,7 +364,7 @@ out_unlock: GEM_BUG_ON(b->first_wait == wait); GEM_BUG_ON(rb_first(&b->waiters) != (b->first_wait ? &b->first_wait->node : NULL)); - GEM_BUG_ON(!b->tasklet ^ RB_EMPTY_ROOT(&b->waiters)); + GEM_BUG_ON(!b->irq_seqno_bh ^ RB_EMPTY_ROOT(&b->waiters)); spin_unlock(&b->lock); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 121294c602c3..12cb7ed90014 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -74,8 +74,8 @@ enum intel_ring_hangcheck_action { struct intel_ring_hangcheck { u64 acthd; + unsigned long user_interrupts; u32 seqno; - unsigned user_interrupts; int score; enum intel_ring_hangcheck_action action; int deadlock; @@ -167,16 +167,20 @@ struct intel_engine_cs { * the overhead of waking that client is much preferred. */ struct intel_breadcrumbs { + struct task_struct *irq_seqno_bh; /* bh for user interrupts */ + unsigned long irq_wakeups; + bool irq_posted; + spinlock_t lock; /* protects the lists of requests */ struct rb_root waiters; /* sorted by retirement, priority */ struct rb_root signals; /* sorted by retirement */ struct intel_wait *first_wait; /* oldest waiter by retirement */ - struct task_struct *tasklet; /* bh for user interrupts */ struct task_struct *signaler; /* used for fence signalling */ struct drm_i915_gem_request *first_signal; struct timer_list fake_irq; /* used after a missed interrupt */ - bool irq_enabled; - bool rpm_wakelock; + + bool irq_enabled : 1; + bool rpm_wakelock : 1; } breadcrumbs; /* @@ -189,7 +193,6 @@ struct intel_engine_cs { struct intel_hw_status_page status_page; struct i915_ctx_workarounds wa_ctx; - bool irq_posted; u32 irq_keep_mask; /* always keep these interrupts */ u32 irq_enable_mask; /* bitmask to enable ring interrupt */ void (*irq_enable)(struct intel_engine_cs *ring); @@ -319,7 +322,6 @@ struct intel_engine_cs { * inspecting request list. */ u32 last_submitted_seqno; - unsigned user_interrupts; bool gpu_caches_dirty; @@ -543,13 +545,13 @@ void intel_engine_enable_signaling(struct drm_i915_gem_request *request); static inline bool intel_engine_has_waiter(struct intel_engine_cs *engine) { - return READ_ONCE(engine->breadcrumbs.tasklet); + return READ_ONCE(engine->breadcrumbs.irq_seqno_bh); } static inline bool intel_engine_wakeup(struct intel_engine_cs *engine) { bool wakeup = false; - struct task_struct *tsk = READ_ONCE(engine->breadcrumbs.tasklet); + struct task_struct *tsk = READ_ONCE(engine->breadcrumbs.irq_seqno_bh); /* Note that for this not to dangerously chase a dangling pointer, * the caller is responsible for ensure that the task remain valid for * wake_up_process() i.e. that the RCU grace period cannot expire. -- cgit v1.2.3 From ab0e455bd0abe2b817c896b229b08045bafbdb94 Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Wed, 6 Jul 2016 15:30:11 +0100 Subject: drm/i915: avoid wait_for_atomic() in non-atomic host2guc_action() Rather than using wait_for_atomic() when chacking for a response from the GuC, we can get the effect of a hybrid spin/sleep wait by breaking it into two stages. First, spin-wait for up to 10us to minimise latency for "quick" commands; then, if that times out, sleep-wait for up 10ms (the maximum allowed for a "slow" command). Being able to do this depends on the recent patch 18f4b84 drm/i915: Use atomic waits for short non-atomic ones and is similar to the hybrid approach in 1758b90 drm/i915: Use a hybrid scheme for fast register waits (although we can't use that as-is, because that interface doesn't quite match what we need here). Signed-off-by: Dave Gordon Cc: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467815411-21756-1-git-send-email-david.s.gordon@intel.com --- drivers/gpu/drm/i915/i915_guc_submission.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index bfc8bf672f2d..2112e029db6a 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -97,8 +97,14 @@ static int host2guc_action(struct intel_guc *guc, u32 *data, u32 len) I915_WRITE(HOST2GUC_INTERRUPT, HOST2GUC_TRIGGER); - /* No HOST2GUC command should take longer than 10ms */ - ret = wait_for_atomic(host2guc_action_response(dev_priv, &status), 10); + /* + * Fast commands should complete in less than 10us, so sample quickly + * up to that length of time, then switch to a slower sleep-wait loop. + * No HOST2GUC command should ever take longer than 10ms. + */ + ret = wait_for_us(host2guc_action_response(dev_priv, &status), 10); + if (ret) + ret = wait_for(host2guc_action_response(dev_priv, &status), 10); if (status != GUC2HOST_STATUS_SUCCESS) { /* * Either the GuC explicitly returned an error (which -- cgit v1.2.3 From f8e58ddf856260b859d77c0f60bb1fa419a0bad3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:56:59 +0300 Subject: drm/i915: Don't mark eDP encoders as MST capable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we've determined that the encoder is eDP, we shouldn't try to use MST on it. Or at least the code doesn't seem to expect that since there are some type==DP checks in the MST code. Cc: Dave Airlie Signed-off-by: Ville Syrjälä Reviewed-by: Shashank Sharma Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-2-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5e4d894968d6..2b60c7f2f149 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5615,7 +5615,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, } /* init MST on ports that can support it */ - if (HAS_DP_MST(dev) && + if (HAS_DP_MST(dev) && !is_edp(intel_dp) && (port == PORT_B || port == PORT_C || port == PORT_D)) intel_dp_mst_encoder_init(intel_dig_port, intel_connector->base.base.id); -- cgit v1.2.3 From 5aa56969629ac87a1bd9605b432926f21ccf4a98 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:00 +0300 Subject: drm/i915: Remove encoder type checks from MST suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that eDP encoders won't have can_mst==true, we can throw out the encoder type checks from the MST suspend/resume paths. Cc: Dave Airlie Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-3-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_dp.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2b60c7f2f149..66dd8ff52e17 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -5733,15 +5733,12 @@ void intel_dp_mst_suspend(struct drm_device *dev) /* disable MST */ for (i = 0; i < I915_MAX_PORTS; i++) { struct intel_digital_port *intel_dig_port = dev_priv->hotplug.irq_port[i]; - if (!intel_dig_port) + + if (!intel_dig_port || !intel_dig_port->dp.can_mst) continue; - if (intel_dig_port->base.type == INTEL_OUTPUT_DISPLAYPORT) { - if (!intel_dig_port->dp.can_mst) - continue; - if (intel_dig_port->dp.is_mst) - drm_dp_mst_topology_mgr_suspend(&intel_dig_port->dp.mst_mgr); - } + if (intel_dig_port->dp.is_mst) + drm_dp_mst_topology_mgr_suspend(&intel_dig_port->dp.mst_mgr); } } @@ -5752,18 +5749,13 @@ void intel_dp_mst_resume(struct drm_device *dev) for (i = 0; i < I915_MAX_PORTS; i++) { struct intel_digital_port *intel_dig_port = dev_priv->hotplug.irq_port[i]; - if (!intel_dig_port) - continue; - if (intel_dig_port->base.type == INTEL_OUTPUT_DISPLAYPORT) { - int ret; + int ret; - if (!intel_dig_port->dp.can_mst) - continue; + if (!intel_dig_port || !intel_dig_port->dp.can_mst) + continue; - ret = drm_dp_mst_topology_mgr_resume(&intel_dig_port->dp.mst_mgr); - if (ret != 0) { - intel_dp_check_mst_status(&intel_dig_port->dp); - } - } + ret = drm_dp_mst_topology_mgr_resume(&intel_dig_port->dp.mst_mgr); + if (ret) + intel_dp_check_mst_status(&intel_dig_port->dp); } } -- cgit v1.2.3 From 253c84c82aaeb9c68e07a9ef0df0a3172b3d37fc Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:01 +0300 Subject: drm/i915: Add output_types bitmask into the crtc state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than looping through encoders to see which encoder types are being driven by the pipe, add an output_types bitmask into the crtc state and populate it prior to compute_config and during state readout. v2: Determine output_types before .compute_config() hooks are called Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-4-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 51 +++++++++++++++--------------------- drivers/gpu/drm/i915/intel_drv.h | 5 ++++ 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 111b350d1d7e..5c375813db13 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -535,14 +535,7 @@ needs_modeset(struct drm_crtc_state *state) */ bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type) { - struct drm_device *dev = crtc->base.dev; - struct intel_encoder *encoder; - - for_each_encoder_on_crtc(dev, &crtc->base, encoder) - if (encoder->type == type) - return true; - - return false; + return crtc->config->output_types & (1 << type); } /** @@ -552,28 +545,9 @@ bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type) * encoder->crtc. */ static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state, - int type) + enum intel_output_type type) { - struct drm_atomic_state *state = crtc_state->base.state; - struct drm_connector *connector; - struct drm_connector_state *connector_state; - struct intel_encoder *encoder; - int i, num_connectors = 0; - - for_each_connector_in_state(state, connector, connector_state, i) { - if (connector_state->crtc != crtc_state->base.crtc) - continue; - - num_connectors++; - - encoder = to_intel_encoder(connector_state->best_encoder); - if (encoder->type == type) - return true; - } - - WARN_ON(num_connectors == 0); - - return false; + return crtc_state->output_types & (1 << type); } /* @@ -12544,6 +12518,19 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, &pipe_config->pipe_src_w, &pipe_config->pipe_src_h); + for_each_connector_in_state(state, connector, connector_state, i) { + if (connector_state->crtc != crtc) + continue; + + encoder = to_intel_encoder(connector_state->best_encoder); + + /* + * Determine output_types before calling the .compute_config() + * hooks so that the hooks can use this information safely. + */ + pipe_config->output_types |= 1 << encoder->type; + } + encoder_retry: /* Ensure the port clock defaults are reset when retrying. */ pipe_config->port_clock = 0; @@ -12842,6 +12829,7 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2); PIPE_CONF_CHECK_I(has_dsi_encoder); + PIPE_CONF_CHECK_X(output_types); PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay); PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal); @@ -13109,8 +13097,10 @@ verify_crtc_state(struct drm_crtc *crtc, "Encoder connected to wrong pipe %c\n", pipe_name(pipe)); - if (active) + if (active) { + pipe_config->output_types |= 1 << encoder->type; encoder->get_config(encoder, pipe_config); + } } if (!new_crtc_state->active) @@ -16075,6 +16065,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) if (encoder->get_hw_state(encoder, &pipe)) { crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); encoder->base.crtc = &crtc->base; + crtc->config->output_types |= 1 << encoder->type; encoder->get_config(encoder, crtc->config); } else { encoder->base.crtc = NULL; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e6a24d2154d1..4d676d0baa87 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -529,6 +529,11 @@ struct intel_crtc_state { /* DSI has special cases */ bool has_dsi_encoder; + /* Bitmask of encoder types (enum intel_output_type) + * driven by the pipe. + */ + unsigned int output_types; + /* Whether we should send NULL infoframes. Required for audio. */ bool has_hdmi_sink; -- cgit v1.2.3 From 2d84d2b367541fa59855e9df20b1f077d72a6fd2 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:02 +0300 Subject: drm/i915: Unify intel_pipe_has_type() and intel_pipe_will_have_type() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the introduction of the output_types mask, intel_pipe_has_type() and intel_pipe_will_have_type() are basically the same thing. Replace them with a new intel_crtc_has_type() (identical to intel_pipe_will_have_type() actually). v2: Rebase v3: Make intel_crtc_has_type() static inline (Chris) Cc: Chris Wilson Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst (v2) Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-5-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_audio.c | 12 ++--- drivers/gpu/drm/i915/intel_display.c | 85 ++++++++++++++---------------------- drivers/gpu/drm/i915/intel_drv.h | 7 ++- 3 files changed, 45 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 161f6c2bca36..98d2a45ea46d 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -154,7 +154,7 @@ static bool audio_rate_need_prog(struct intel_crtc *crtc, { if (((mode->clock == TMDS_297M) || (mode->clock == TMDS_296M)) && - intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) + intel_crtc_has_type(crtc->config, INTEL_OUTPUT_HDMI)) return true; else return false; @@ -262,7 +262,7 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder) tmp |= AUD_CONFIG_N_PROG_ENABLE; tmp &= ~AUD_CONFIG_UPPER_N_MASK; tmp &= ~AUD_CONFIG_LOWER_N_MASK; - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DISPLAYPORT)) tmp |= AUD_CONFIG_N_VALUE_INDEX; I915_WRITE(HSW_AUD_CFG(pipe), tmp); @@ -328,7 +328,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, tmp = I915_READ(HSW_AUD_CFG(pipe)); tmp &= ~AUD_CONFIG_N_VALUE_INDEX; tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DISPLAYPORT)) tmp |= AUD_CONFIG_N_VALUE_INDEX; else tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); @@ -389,7 +389,7 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder) tmp |= AUD_CONFIG_N_PROG_ENABLE; tmp &= ~AUD_CONFIG_UPPER_N_MASK; tmp &= ~AUD_CONFIG_LOWER_N_MASK; - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DISPLAYPORT)) tmp |= AUD_CONFIG_N_VALUE_INDEX; I915_WRITE(aud_config, tmp); @@ -475,7 +475,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, tmp &= ~AUD_CONFIG_N_VALUE_INDEX; tmp &= ~AUD_CONFIG_N_PROG_ENABLE; tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DISPLAYPORT)) tmp |= AUD_CONFIG_N_VALUE_INDEX; else tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); @@ -513,7 +513,7 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder) /* ELD Conn_Type */ connector->eld[5] &= ~(3 << 2); - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DISPLAYPORT)) connector->eld[5] |= (1 << 2); connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5c375813db13..a187777309c5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -530,26 +530,6 @@ needs_modeset(struct drm_crtc_state *state) return drm_atomic_crtc_needs_modeset(state); } -/** - * Returns whether any output on the specified pipe is of the specified type - */ -bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type) -{ - return crtc->config->output_types & (1 << type); -} - -/** - * Returns whether any output on the specified pipe will have the specified - * type after a staged modeset is complete, i.e., the same as - * intel_pipe_has_type() but looking at encoder->new_crtc instead of - * encoder->crtc. - */ -static bool intel_pipe_will_have_type(const struct intel_crtc_state *crtc_state, - enum intel_output_type type) -{ - return crtc_state->output_types & (1 << type); -} - /* * Platform specific helpers to calculate the port PLL loopback- (clock.m), * and post-divider (clock.p) values, pre- (clock.vco) and post-divided fast @@ -662,7 +642,7 @@ i9xx_select_p2_div(const struct intel_limit *limit, { struct drm_device *dev = crtc_state->base.crtc->dev; - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { /* * For LVDS just rely on its current settings for dual-channel. * We haven't figured out how to reliably set up different @@ -1620,9 +1600,10 @@ static int intel_num_dvo_pipes(struct drm_device *dev) struct intel_crtc *crtc; int count = 0; - for_each_intel_crtc(dev, crtc) + for_each_intel_crtc(dev, crtc) { count += crtc->base.state->active && - intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO); + intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DVO); + } return count; } @@ -1707,7 +1688,7 @@ static void i9xx_disable_pll(struct intel_crtc *crtc) /* Disable DVO 2x clock on both PLLs if necessary */ if (IS_I830(dev) && - intel_pipe_has_type(crtc, INTEL_OUTPUT_DVO) && + intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DVO) && !intel_num_dvo_pipes(dev)) { I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) & ~DPLL_DVO_2X_MODE); @@ -1837,7 +1818,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, * here for both 8bpc and 12bpc. */ val &= ~PIPECONF_BPC_MASK; - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_HDMI)) + if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_HDMI)) val |= PIPECONF_8BPC; else val |= pipeconf_val & PIPECONF_BPC_MASK; @@ -1846,7 +1827,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv, val &= ~TRANS_INTERLACE_MASK; if ((pipeconf_val & PIPECONF_INTERLACE_MASK) == PIPECONF_INTERLACED_ILK) if (HAS_PCH_IBX(dev_priv) && - intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO)) + intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_SDVO)) val |= TRANS_LEGACY_INTERLACED_ILK; else val |= TRANS_INTERLACED; @@ -6667,7 +6648,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc, * - LVDS dual channel mode * - Double wide pipe */ - if ((intel_pipe_will_have_type(pipe_config, INTEL_OUTPUT_LVDS) && + if ((intel_crtc_has_type(pipe_config, INTEL_OUTPUT_LVDS) && intel_is_dual_link_lvds(dev)) || pipe_config->double_wide) pipe_config->pipe_src_w &= ~1; @@ -7178,7 +7159,7 @@ static void i9xx_update_pll_dividers(struct intel_crtc *crtc, crtc_state->dpll_hw_state.fp0 = fp; crtc->lowfreq_avail = false; - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && reduced_clock) { crtc_state->dpll_hw_state.fp1 = fp2; crtc->lowfreq_avail = true; @@ -7384,8 +7365,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, /* Set HBR and RBR LPF coefficients */ if (pipe_config->port_clock == 162000 || - intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) + intel_crtc_has_type(crtc->config, INTEL_OUTPUT_ANALOG) || + intel_crtc_has_type(crtc->config, INTEL_OUTPUT_HDMI)) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe), 0x009f0003); else @@ -7412,8 +7393,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe)); coreclk = (coreclk & 0x0000ff00) | 0x01c00000; - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) + if (intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DISPLAYPORT) || + intel_crtc_has_type(crtc->config, INTEL_OUTPUT_EDP)) coreclk |= 0x01000000; vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk); @@ -7594,12 +7575,12 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock); - is_sdvo = intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO) || - intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI); + is_sdvo = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) || + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI); dpll = DPLL_VGA_MODE_DIS; - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) dpll |= DPLLB_MODE_LVDS; else dpll |= DPLLB_MODE_DAC_SERIAL; @@ -7642,7 +7623,7 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, if (crtc_state->sdvo_tv_clock) dpll |= PLL_REF_INPUT_TVCLKINBC; - else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv)) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else @@ -7671,7 +7652,7 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc, dpll = DPLL_VGA_MODE_DIS; - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; } else { if (clock->p1 == 2) @@ -7682,10 +7663,10 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc, dpll |= PLL_P2_DIVIDE_BY_4; } - if (!IS_I830(dev) && intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO)) + if (!IS_I830(dev) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO)) dpll |= DPLL_DVO_2X_MODE; - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && intel_panel_use_ssc(dev_priv)) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else @@ -7715,7 +7696,7 @@ static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) crtc_vtotal -= 1; crtc_vblank_end -= 1; - if (intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO)) + if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_SDVO)) vsyncshift = (adjusted_mode->crtc_htotal - 1) / 2; else vsyncshift = adjusted_mode->crtc_hsync_start - @@ -7894,7 +7875,7 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc) if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { if (INTEL_INFO(dev)->gen < 4 || - intel_pipe_has_type(intel_crtc, INTEL_OUTPUT_SDVO)) + intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_SDVO)) pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; else pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT; @@ -7920,14 +7901,14 @@ static int i8xx_crtc_compute_clock(struct intel_crtc *crtc, memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); } limit = &intel_limits_i8xx_lvds; - } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_DVO)) { + } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO)) { limit = &intel_limits_i8xx_dvo; } else { limit = &intel_limits_i8xx_dac; @@ -7956,7 +7937,7 @@ static int g4x_crtc_compute_clock(struct intel_crtc *crtc, memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); @@ -7966,10 +7947,10 @@ static int g4x_crtc_compute_clock(struct intel_crtc *crtc, limit = &intel_limits_g4x_dual_channel_lvds; else limit = &intel_limits_g4x_single_channel_lvds; - } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_HDMI) || - intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_ANALOG)) { + } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) || + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { limit = &intel_limits_g4x_hdmi; - } else if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_SDVO)) { + } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) { limit = &intel_limits_g4x_sdvo; } else { /* The option is for other outputs */ @@ -7999,7 +7980,7 @@ static int pnv_crtc_compute_clock(struct intel_crtc *crtc, memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); @@ -8033,7 +8014,7 @@ static int i9xx_crtc_compute_clock(struct intel_crtc *crtc, memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", refclk); @@ -9034,7 +9015,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, if (!crtc_state->has_pch_encoder) return 0; - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS)) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { DRM_DEBUG_KMS("using SSC reference clock of %d kHz\n", dev_priv->vbt.lvds_ssc_freq); @@ -9073,7 +9054,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc, return -EINVAL; } - if (intel_pipe_will_have_type(crtc_state, INTEL_OUTPUT_LVDS) && + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && has_reduced_clock) crtc->lowfreq_avail = true; @@ -13265,7 +13246,7 @@ static void update_scanline_offset(struct intel_crtc *crtc) crtc->scanline_offset = vtotal - 1; } else if (HAS_DDI(dev) && - intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { + intel_crtc_has_type(crtc->config, INTEL_OUTPUT_HDMI)) { crtc->scanline_offset = 2; } else crtc->scanline_offset = 1; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4d676d0baa87..f4710558150f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1192,7 +1192,12 @@ int intel_get_pipe_from_crtc_id(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); -bool intel_pipe_has_type(struct intel_crtc *crtc, enum intel_output_type type); +static inline bool +intel_crtc_has_type(const struct intel_crtc_state *crtc_state, + enum intel_output_type type) +{ + return crtc_state->output_types & (1 << type); +} static inline void intel_wait_for_vblank(struct drm_device *dev, int pipe) { -- cgit v1.2.3 From 3d6e9ee0e125548c94417368ba53334445939bfd Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:03 +0300 Subject: drm/i915: Replace manual lvds and sdvo/hdmi counting with intel_crtc_has_type() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we now have the output_types bitmaks in the crtc state, there's no need to iterate through all the encoders to see if an LVDS or SDVO/HDMI encoder might be present. Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-6-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 44 ++++++++---------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a187777309c5..9f2ed96fda7a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7570,14 +7570,10 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); u32 dpll; - bool is_sdvo; struct dpll *clock = &crtc_state->dpll; i9xx_update_pll_dividers(crtc, crtc_state, reduced_clock); - is_sdvo = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) || - intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI); - dpll = DPLL_VGA_MODE_DIS; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) @@ -7590,7 +7586,8 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, << SDVO_MULTIPLIER_SHIFT_HIRES; } - if (is_sdvo) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) || + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) dpll |= DPLL_SDVO_HIGH_SPEED; if (crtc_state->has_dp_encoder) @@ -8897,36 +8894,12 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, struct drm_crtc *crtc = &intel_crtc->base; struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = to_i915(dev); - struct drm_atomic_state *state = crtc_state->base.state; - struct drm_connector *connector; - struct drm_connector_state *connector_state; - struct intel_encoder *encoder; u32 dpll, fp, fp2; - int factor, i; - bool is_lvds = false, is_sdvo = false; - - for_each_connector_in_state(state, connector, connector_state, i) { - if (connector_state->crtc != crtc_state->base.crtc) - continue; - - encoder = to_intel_encoder(connector_state->best_encoder); - - switch (encoder->type) { - case INTEL_OUTPUT_LVDS: - is_lvds = true; - break; - case INTEL_OUTPUT_SDVO: - case INTEL_OUTPUT_HDMI: - is_sdvo = true; - break; - default: - break; - } - } + int factor; /* Enable autotuning of the PLL clock (if permissible) */ factor = 21; - if (is_lvds) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if ((intel_panel_use_ssc(dev_priv) && dev_priv->vbt.lvds_ssc_freq == 100000) || (HAS_PCH_IBX(dev) && intel_is_dual_link_lvds(dev))) @@ -8950,7 +8923,7 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, dpll = 0; - if (is_lvds) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) dpll |= DPLLB_MODE_LVDS; else dpll |= DPLLB_MODE_DAC_SERIAL; @@ -8958,8 +8931,10 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, dpll |= (crtc_state->pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; - if (is_sdvo) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO) || + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) dpll |= DPLL_SDVO_HIGH_SPEED; + if (crtc_state->has_dp_encoder) dpll |= DPLL_SDVO_HIGH_SPEED; @@ -8983,7 +8958,8 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, break; } - if (is_lvds && intel_panel_use_ssc(dev_priv)) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv)) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; -- cgit v1.2.3 From 37a5650b5bd645d74f082f2cffd22e4db7f4b238 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:04 +0300 Subject: drm/i915: Kill has_dp_encoder from pipe_config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new output_types bitmask instead of has_dp_encoder. To make it less oainlful provide a small helper (intel_crtc_has_dp_encoder()) to do the bitsy stuff. v2: Rebase Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-7-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 3 +-- drivers/gpu/drm/i915/intel_display.c | 21 ++++++++++----------- drivers/gpu/drm/i915/intel_dp.c | 3 --- drivers/gpu/drm/i915/intel_dp_mst.c | 3 --- drivers/gpu/drm/i915/intel_drv.h | 12 ++++++++---- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index d6efe8bf813b..aa12d0e9bb93 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -834,7 +834,7 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) if (pipe_config->has_pch_encoder) dotclock = intel_dotclock_calculate(pipe_config->port_clock, &pipe_config->fdi_m_n); - else if (pipe_config->has_dp_encoder) + else if (intel_crtc_has_dp_encoder(pipe_config)) dotclock = intel_dotclock_calculate(pipe_config->port_clock, &pipe_config->dp_m_n); else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36) @@ -2211,7 +2211,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder, break; case TRANS_DDI_MODE_SELECT_DP_SST: case TRANS_DDI_MODE_SELECT_DP_MST: - pipe_config->has_dp_encoder = true; pipe_config->lane_count = ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; intel_dp_get_m_n(intel_crtc, pipe_config); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9f2ed96fda7a..15cb1e20a490 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4109,7 +4109,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) intel_fdi_normal_train(crtc); /* For PCH DP, enable TRANS_DP_CTL */ - if (HAS_PCH_CPT(dev) && intel_crtc->config->has_dp_encoder) { + if (HAS_PCH_CPT(dev) && intel_crtc_has_dp_encoder(intel_crtc->config)) { const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode; u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5; @@ -4735,7 +4735,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->config->has_pch_encoder) intel_prepare_shared_dpll(intel_crtc); - if (intel_crtc->config->has_dp_encoder) + if (intel_crtc_has_dp_encoder(intel_crtc->config)) intel_dp_set_m_n(intel_crtc, M1_N1); intel_set_pipe_timings(intel_crtc); @@ -4826,7 +4826,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->config->shared_dpll) intel_enable_shared_dpll(intel_crtc); - if (intel_crtc->config->has_dp_encoder) + if (intel_crtc_has_dp_encoder(intel_crtc->config)) intel_dp_set_m_n(intel_crtc, M1_N1); if (!intel_crtc->config->has_dsi_encoder) @@ -6129,7 +6129,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) if (WARN_ON(intel_crtc->active)) return; - if (intel_crtc->config->has_dp_encoder) + if (intel_crtc_has_dp_encoder(intel_crtc->config)) intel_dp_set_m_n(intel_crtc, M1_N1); intel_set_pipe_timings(intel_crtc); @@ -6202,7 +6202,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) i9xx_set_pll_dividers(intel_crtc); - if (intel_crtc->config->has_dp_encoder) + if (intel_crtc_has_dp_encoder(intel_crtc->config)) intel_dp_set_m_n(intel_crtc, M1_N1); intel_set_pipe_timings(intel_crtc); @@ -7373,7 +7373,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW10(pipe), 0x00d0000f); - if (pipe_config->has_dp_encoder) { + if (intel_crtc_has_dp_encoder(pipe_config)) { /* Use SSC source */ if (pipe == PIPE_A) vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW5(pipe), @@ -7590,7 +7590,7 @@ static void i9xx_compute_dpll(struct intel_crtc *crtc, intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) dpll |= DPLL_SDVO_HIGH_SPEED; - if (crtc_state->has_dp_encoder) + if (intel_crtc_has_dp_encoder(crtc_state)) dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ @@ -8935,7 +8935,7 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc, intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) dpll |= DPLL_SDVO_HIGH_SPEED; - if (crtc_state->has_dp_encoder) + if (intel_crtc_has_dp_encoder(crtc_state)) dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ @@ -12238,14 +12238,14 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, pipe_config->fdi_m_n.link_m, pipe_config->fdi_m_n.link_n, pipe_config->fdi_m_n.tu); DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n", - pipe_config->has_dp_encoder, + intel_crtc_has_dp_encoder(pipe_config), pipe_config->lane_count, pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n, pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n, pipe_config->dp_m_n.tu); DRM_DEBUG_KMS("dp: %i, lanes: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n", - pipe_config->has_dp_encoder, + intel_crtc_has_dp_encoder(pipe_config), pipe_config->lane_count, pipe_config->dp_m2_n2.gmch_m, pipe_config->dp_m2_n2.gmch_n, @@ -12773,7 +12773,6 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_I(fdi_lanes); PIPE_CONF_CHECK_M_N(fdi_m_n); - PIPE_CONF_CHECK_I(has_dp_encoder); PIPE_CONF_CHECK_I(lane_count); PIPE_CONF_CHECK_X(lane_lat_optim_mask); diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 66dd8ff52e17..3a392c42cd3d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1501,7 +1501,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A) pipe_config->has_pch_encoder = true; - pipe_config->has_dp_encoder = true; pipe_config->has_drrs = false; pipe_config->has_audio = intel_dp->has_audio && port != PORT_A; @@ -2442,8 +2441,6 @@ static void intel_dp_get_config(struct intel_encoder *encoder, !IS_CHERRYVIEW(dev) && tmp & DP_COLOR_RANGE_16_235) pipe_config->limited_color_range = true; - pipe_config->has_dp_encoder = true; - pipe_config->lane_count = ((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1; diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 81800877b1af..68a005d729e9 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -47,7 +47,6 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->dp_encoder_is_mst = true; pipe_config->has_pch_encoder = false; - pipe_config->has_dp_encoder = true; bpp = 24; /* * for MST we always configure max link bw - the spec doesn't @@ -246,8 +245,6 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; u32 temp, flags = 0; - pipe_config->has_dp_encoder = true; - temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); if (temp & TRANS_DDI_PHSYNC) flags |= DRM_MODE_FLAG_PHSYNC; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f4710558150f..de8e64395ff3 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -522,10 +522,6 @@ struct intel_crtc_state { */ bool limited_color_range; - /* DP has a bunch of special case unfortunately, so mark the pipe - * accordingly. */ - bool has_dp_encoder; - /* DSI has special cases */ bool has_dsi_encoder; @@ -1198,6 +1194,14 @@ intel_crtc_has_type(const struct intel_crtc_state *crtc_state, { return crtc_state->output_types & (1 << type); } +static inline bool +intel_crtc_has_dp_encoder(const struct intel_crtc_state *crtc_state) +{ + return crtc_state->output_types & + ((1 << INTEL_OUTPUT_DISPLAYPORT) | + (1 << INTEL_OUTPUT_DP_MST) | + (1 << INTEL_OUTPUT_EDP)); +} static inline void intel_wait_for_vblank(struct drm_device *dev, int pipe) { -- cgit v1.2.3 From 2210ce7f537412160e93a5cf9796581858287fb1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:05 +0300 Subject: drm/i915: Replace some open coded intel_crtc_has_dp_encoder()s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A bunch of places still look for DP encoders manually. Just call intel_crtc_has_dp_encoder(). Note that many of these places don't look for EDP or DP_MST, but it's still fine to replace them because * for audio we don't enable audio on eDP anyway * the code that lack DP MST check is only for plaforms that don't support MST anyway v2: Rebase Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-8-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_audio.c | 10 +++++----- drivers/gpu/drm/i915/intel_display.c | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 98d2a45ea46d..6700a7be7f78 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -262,7 +262,7 @@ static void hsw_audio_codec_disable(struct intel_encoder *encoder) tmp |= AUD_CONFIG_N_PROG_ENABLE; tmp &= ~AUD_CONFIG_UPPER_N_MASK; tmp &= ~AUD_CONFIG_LOWER_N_MASK; - if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_dp_encoder(intel_crtc->config)) tmp |= AUD_CONFIG_N_VALUE_INDEX; I915_WRITE(HSW_AUD_CFG(pipe), tmp); @@ -328,7 +328,7 @@ static void hsw_audio_codec_enable(struct drm_connector *connector, tmp = I915_READ(HSW_AUD_CFG(pipe)); tmp &= ~AUD_CONFIG_N_VALUE_INDEX; tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; - if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_dp_encoder(intel_crtc->config)) tmp |= AUD_CONFIG_N_VALUE_INDEX; else tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); @@ -389,7 +389,7 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder) tmp |= AUD_CONFIG_N_PROG_ENABLE; tmp &= ~AUD_CONFIG_UPPER_N_MASK; tmp &= ~AUD_CONFIG_LOWER_N_MASK; - if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_dp_encoder(intel_crtc->config)) tmp |= AUD_CONFIG_N_VALUE_INDEX; I915_WRITE(aud_config, tmp); @@ -475,7 +475,7 @@ static void ilk_audio_codec_enable(struct drm_connector *connector, tmp &= ~AUD_CONFIG_N_VALUE_INDEX; tmp &= ~AUD_CONFIG_N_PROG_ENABLE; tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK; - if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_dp_encoder(intel_crtc->config)) tmp |= AUD_CONFIG_N_VALUE_INDEX; else tmp |= audio_config_hdmi_pixel_clock(adjusted_mode); @@ -513,7 +513,7 @@ void intel_audio_codec_enable(struct intel_encoder *intel_encoder) /* ELD Conn_Type */ connector->eld[5] &= ~(3 << 2); - if (intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DISPLAYPORT)) + if (intel_crtc_has_dp_encoder(crtc->config)) connector->eld[5] |= (1 << 2); connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 15cb1e20a490..9da4befa6fcb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7393,8 +7393,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, coreclk = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW7(pipe)); coreclk = (coreclk & 0x0000ff00) | 0x01c00000; - if (intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DISPLAYPORT) || - intel_crtc_has_type(crtc->config, INTEL_OUTPUT_EDP)) + if (intel_crtc_has_dp_encoder(crtc->config)) coreclk |= 0x01000000; vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk); -- cgit v1.2.3 From cca0502b9c6bf4a289a5e71a9a3794e73973e9e3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:06 +0300 Subject: drm/i915: s/INTEL_OUTPUT_DISPLAYPORT/INTEL_OUTPUT_DP/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit INTEL_OUTPUT_DISPLAYPORT hsa been bugging me for a long time. It always looks out of place besides INTEL_OUTPUT_EDP and INTEL_OUTPUT_DP_MST. Let's just rename it to INTEL_OUTPUT_DP. v2: Rebase Signed-off-by: Ville Syrjälä Reviewed-by: Mika Kahola Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-9-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/intel_ddi.c | 16 ++++++++-------- drivers/gpu/drm/i915/intel_display.c | 8 ++++---- drivers/gpu/drm/i915/intel_dp.c | 10 +++++----- drivers/gpu/drm/i915/intel_dpll_mgr.c | 6 +++--- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_opregion.c | 2 +- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3d05cae0e92d..844fea795bae 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3774,7 +3774,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_device *dev, enum pipe pipe, case INTEL_OUTPUT_TVOUT: *source = INTEL_PIPE_CRC_SOURCE_TV; break; - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_EDP: dig_port = enc_to_dig_port(&encoder->base); switch (dig_port->port) { diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index aa12d0e9bb93..dd1d6fe12297 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -318,7 +318,7 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder, default: WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type); /* fallthrough and treat as unknown */ - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_EDP: case INTEL_OUTPUT_HDMI: case INTEL_OUTPUT_UNKNOWN: @@ -482,7 +482,7 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) ddi_translations = ddi_translations_edp; size = n_edp_entries; break; - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_HDMI: ddi_translations = ddi_translations_dp; size = n_dp_entries; @@ -1068,7 +1068,7 @@ void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) int type = intel_encoder->type; uint32_t temp; - if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) { + if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) { WARN_ON(transcoder_is_dsi(cpu_transcoder)); temp = TRANS_MSA_SYNC_CLK; @@ -1182,7 +1182,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) temp |= TRANS_DDI_MODE_SELECT_FDI; temp |= (intel_crtc->config->fdi_lanes - 1) << 1; - } else if (type == INTEL_OUTPUT_DISPLAYPORT || + } else if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -1392,7 +1392,7 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv, dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level; hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level; - if (type == INTEL_OUTPUT_DISPLAYPORT) { + if (type == INTEL_OUTPUT_DP) { if (dp_iboost) { iboost = dp_iboost; } else { @@ -1450,7 +1450,7 @@ static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) { n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); ddi_translations = bxt_ddi_translations_edp; - } else if (type == INTEL_OUTPUT_DISPLAYPORT + } else if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { n_entries = ARRAY_SIZE(bxt_ddi_translations_dp); ddi_translations = bxt_ddi_translations_dp; @@ -1624,7 +1624,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) intel_ddi_clk_select(intel_encoder, crtc->config); - if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { + if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_dp_set_link_params(intel_dp, crtc->config); @@ -1669,7 +1669,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) if (wait) intel_wait_ddi_buf_idle(dev_priv, port); - if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { + if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); intel_edp_panel_vdd_on(intel_dp); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9da4befa6fcb..907945545f6b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4040,7 +4040,7 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc) struct intel_encoder *encoder; for_each_encoder_on_crtc(dev, crtc, encoder) { - if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + if (encoder->type == INTEL_OUTPUT_DP || encoder->type == INTEL_OUTPUT_EDP) return enc_to_dig_port(&encoder->base)->port; } @@ -5128,7 +5128,7 @@ intel_display_port_power_domain(struct intel_encoder *intel_encoder) case INTEL_OUTPUT_UNKNOWN: /* Only DDI platforms should ever use this output type */ WARN_ON_ONCE(!HAS_DDI(dev)); - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_HDMI: case INTEL_OUTPUT_EDP: intel_dig_port = enc_to_dig_port(&intel_encoder->base); @@ -5162,7 +5162,7 @@ intel_display_port_aux_power_domain(struct intel_encoder *intel_encoder) * run the DP detection too. */ WARN_ON_ONCE(!HAS_DDI(dev)); - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_EDP: intel_dig_port = enc_to_dig_port(&intel_encoder->base); return port_to_aux_power_domain(intel_dig_port->port); @@ -12377,7 +12377,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) case INTEL_OUTPUT_UNKNOWN: if (WARN_ON(!HAS_DDI(dev))) break; - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_HDMI: case INTEL_OUTPUT_EDP: port_mask = 1 << enc_to_dig_port(&encoder->base)->port; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3a392c42cd3d..0c5ba3410a1e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4250,7 +4250,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) } if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + intel_encoder->type = INTEL_OUTPUT_DP; intel_dp_probe_oui(intel_dp); @@ -4326,7 +4326,7 @@ intel_dp_detect(struct drm_connector *connector, bool force) /* MST devices are disconnected from a monitor POV */ intel_dp_unset_edid(intel_dp); if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + intel_encoder->type = INTEL_OUTPUT_DP; return connector_status_disconnected; } @@ -4365,7 +4365,7 @@ intel_dp_force(struct drm_connector *connector) intel_display_power_put(dev_priv, power_domain); if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + intel_encoder->type = INTEL_OUTPUT_DP; } static int intel_dp_get_modes(struct drm_connector *connector) @@ -4678,7 +4678,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && intel_dig_port->base.type != INTEL_OUTPUT_HDMI) - intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; + intel_dig_port->base.type = INTEL_OUTPUT_DP; if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { /* @@ -5694,7 +5694,7 @@ bool intel_dp_init(struct drm_device *dev, intel_dig_port->dp.output_reg = output_reg; intel_dig_port->max_lanes = 4; - intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; + intel_encoder->type = INTEL_OUTPUT_DP; if (IS_CHERRYVIEW(dev)) { if (port == PORT_D) intel_encoder->crtc_mask = 1 << 2; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 9098169b39c3..5c1f2d235ffa 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -713,7 +713,7 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, pll = intel_find_shared_dpll(crtc, crtc_state, DPLL_ID_WRPLL1, DPLL_ID_WRPLL2); - } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + } else if (encoder->type == INTEL_OUTPUT_DP || encoder->type == INTEL_OUTPUT_DP_MST || encoder->type == INTEL_OUTPUT_EDP) { enum intel_dpll_id pll_id; @@ -1226,7 +1226,7 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, DPLL_CFGCR2_KDIV(wrpll_params.kdiv) | DPLL_CFGCR2_PDIV(wrpll_params.pdiv) | wrpll_params.central_freq; - } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + } else if (encoder->type == INTEL_OUTPUT_DP || encoder->type == INTEL_OUTPUT_DP_MST || encoder->type == INTEL_OUTPUT_EDP) { switch (crtc_state->port_clock / 2) { @@ -1534,7 +1534,7 @@ bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, clk_div.m2_frac_en = clk_div.m2_frac != 0; vco = best_clock.vco; - } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + } else if (encoder->type == INTEL_OUTPUT_DP || encoder->type == INTEL_OUTPUT_EDP) { int i; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index de8e64395ff3..f26befedcf25 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -159,7 +159,7 @@ enum intel_output_type { INTEL_OUTPUT_LVDS = 4, INTEL_OUTPUT_TVOUT = 5, INTEL_OUTPUT_HDMI = 6, - INTEL_OUTPUT_DISPLAYPORT = 7, + INTEL_OUTPUT_DP = 7, INTEL_OUTPUT_EDP = 8, INTEL_OUTPUT_DSI = 9, INTEL_OUTPUT_UNKNOWN = 10, @@ -1198,7 +1198,7 @@ static inline bool intel_crtc_has_dp_encoder(const struct intel_crtc_state *crtc_state) { return crtc_state->output_types & - ((1 << INTEL_OUTPUT_DISPLAYPORT) | + ((1 << INTEL_OUTPUT_DP) | (1 << INTEL_OUTPUT_DP_MST) | (1 << INTEL_OUTPUT_EDP)); } diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 87a9bd040106..c27d5eb063d0 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -383,7 +383,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, type = DISPLAY_TYPE_CRT; break; case INTEL_OUTPUT_UNKNOWN: - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_HDMI: case INTEL_OUTPUT_DP_MST: type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL; -- cgit v1.2.3 From d7edc4e57bfefc5c2830a01f013cebdb814f8ffb Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:07 +0300 Subject: drm/i915: Kill has_dsi_encoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit has_dsi_encoder was introduced to indicate that the pipe is driving a DSI encoder. Now that we have the output_types bitmask that can tell us the same thing, let's just kill has_dsi_encoder. v2: Rebase, handle BXT DSI transcoder, rewrote commit message Cc: Jani Nikula Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-10-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 47 +++++++++++++++--------------------- drivers/gpu/drm/i915/intel_drv.h | 3 --- drivers/gpu/drm/i915/intel_dsi.c | 4 --- 4 files changed, 20 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 2523a5b86dbe..bc0fef3d3335 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -272,7 +272,7 @@ static void i9xx_load_luts_internal(struct drm_crtc *crtc, int i; if (HAS_GMCH_DISPLAY(dev)) { - if (intel_crtc->config->has_dsi_encoder) + if (intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DSI)) assert_dsi_pll_enabled(dev_priv); else assert_pll_enabled(dev_priv, pipe); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 907945545f6b..8704355e471a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1959,7 +1959,7 @@ static void intel_enable_pipe(struct intel_crtc *crtc) * need the check. */ if (HAS_GMCH_DISPLAY(dev_priv)) - if (crtc->config->has_dsi_encoder) + if (intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DSI)) assert_dsi_pll_enabled(dev_priv); else assert_pll_enabled(dev_priv, pipe); @@ -4829,7 +4829,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (intel_crtc_has_dp_encoder(intel_crtc->config)) intel_dp_set_m_n(intel_crtc, M1_N1); - if (!intel_crtc->config->has_dsi_encoder) + if (!transcoder_is_dsi(cpu_transcoder)) intel_set_pipe_timings(intel_crtc); intel_set_pipe_src_size(intel_crtc); @@ -4845,7 +4845,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) &intel_crtc->config->fdi_m_n, NULL); } - if (!intel_crtc->config->has_dsi_encoder) + if (!transcoder_is_dsi(cpu_transcoder)) haswell_set_pipeconf(crtc); haswell_set_pipemisc(crtc); @@ -4867,7 +4867,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->config->has_pch_encoder) dev_priv->display.fdi_link_train(crtc); - if (!intel_crtc->config->has_dsi_encoder) + if (!transcoder_is_dsi(cpu_transcoder)) intel_ddi_enable_pipe_clock(intel_crtc); if (INTEL_INFO(dev)->gen >= 9) @@ -4882,7 +4882,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_color_load_luts(&pipe_config->base); intel_ddi_set_pipe_settings(crtc); - if (!intel_crtc->config->has_dsi_encoder) + if (!transcoder_is_dsi(cpu_transcoder)) intel_ddi_enable_transcoder_func(crtc); if (dev_priv->display.initial_watermarks != NULL) @@ -4891,7 +4891,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_update_watermarks(crtc); /* XXX: Do the pipe assertions at the right place for BXT DSI. */ - if (!intel_crtc->config->has_dsi_encoder) + if (!transcoder_is_dsi(cpu_transcoder)) intel_enable_pipe(intel_crtc); if (intel_crtc->config->has_pch_encoder) @@ -5024,13 +5024,13 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) assert_vblank_disabled(crtc); /* XXX: Do the pipe assertions at the right place for BXT DSI. */ - if (!intel_crtc->config->has_dsi_encoder) + if (!transcoder_is_dsi(cpu_transcoder)) intel_disable_pipe(intel_crtc); if (intel_crtc->config->dp_encoder_is_mst) intel_ddi_set_vc_payload_alloc(crtc, false); - if (!intel_crtc->config->has_dsi_encoder) + if (!transcoder_is_dsi(cpu_transcoder)) intel_ddi_disable_transcoder_func(dev_priv, cpu_transcoder); if (INTEL_INFO(dev)->gen >= 9) @@ -5038,7 +5038,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) else ironlake_pfit_disable(intel_crtc, false); - if (!intel_crtc->config->has_dsi_encoder) + if (!transcoder_is_dsi(cpu_transcoder)) intel_ddi_disable_pipe_clock(intel_crtc); for_each_encoder_on_crtc(dev, crtc, encoder) @@ -6279,7 +6279,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) if (encoder->post_disable) encoder->post_disable(encoder); - if (!intel_crtc->config->has_dsi_encoder) { + if (!intel_crtc_has_type(intel_crtc->config, INTEL_OUTPUT_DSI)) { if (IS_CHERRYVIEW(dev)) chv_disable_pll(dev_priv, pipe); else if (IS_VALLEYVIEW(dev)) @@ -7278,7 +7278,7 @@ static void vlv_compute_dpll(struct intel_crtc *crtc, pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; /* DPLL not used with DSI, but still need the rest set up */ - if (!pipe_config->has_dsi_encoder) + if (!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DSI)) pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV; @@ -7295,7 +7295,7 @@ static void chv_compute_dpll(struct intel_crtc *crtc, pipe_config->dpll_hw_state.dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; /* DPLL not used with DSI, but still need the rest set up */ - if (!pipe_config->has_dsi_encoder) + if (!intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DSI)) pipe_config->dpll_hw_state.dpll |= DPLL_VCO_ENABLE; pipe_config->dpll_hw_state.dpll_md = @@ -9858,10 +9858,7 @@ static void skl_modeset_commit_cdclk(struct drm_atomic_state *old_state) static int haswell_crtc_compute_clock(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state) { - struct intel_encoder *intel_encoder = - intel_ddi_get_crtc_new_encoder(crtc_state); - - if (intel_encoder->type != INTEL_OUTPUT_DSI) { + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) { if (!intel_ddi_pll_select(crtc, crtc_state)) return -EINVAL; } @@ -10028,8 +10025,6 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, enum transcoder cpu_transcoder; u32 tmp; - pipe_config->has_dsi_encoder = false; - for_each_port_masked(port, BIT(PORT_A) | BIT(PORT_C)) { if (port == PORT_A) cpu_transcoder = TRANSCODER_DSI_A; @@ -10061,11 +10056,10 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, continue; pipe_config->cpu_transcoder = cpu_transcoder; - pipe_config->has_dsi_encoder = true; break; } - return pipe_config->has_dsi_encoder; + return transcoder_is_dsi(pipe_config->cpu_transcoder); } static void haswell_get_ddi_port_state(struct intel_crtc *crtc, @@ -10129,18 +10123,16 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask); - if (IS_BROXTON(dev_priv)) { - bxt_get_dsi_transcoder_state(crtc, pipe_config, - &power_domain_mask); - WARN_ON(active && pipe_config->has_dsi_encoder); - if (pipe_config->has_dsi_encoder) - active = true; + if (IS_BROXTON(dev_priv) && + bxt_get_dsi_transcoder_state(crtc, pipe_config, &power_domain_mask)) { + WARN_ON(active); + active = true; } if (!active) goto out; - if (!pipe_config->has_dsi_encoder) { + if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) { haswell_get_ddi_port_state(crtc, pipe_config); intel_get_pipe_timings(crtc, pipe_config); } @@ -12783,7 +12775,6 @@ intel_pipe_config_compare(struct drm_device *dev, } else PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2); - PIPE_CONF_CHECK_I(has_dsi_encoder); PIPE_CONF_CHECK_X(output_types); PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f26befedcf25..55aeaf041749 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -522,9 +522,6 @@ struct intel_crtc_state { */ bool limited_color_range; - /* DSI has special cases */ - bool has_dsi_encoder; - /* Bitmask of encoder types (enum intel_output_type) * driven by the pipe. */ diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 51109ac945bf..de8e9fb51595 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -325,8 +325,6 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder, DRM_DEBUG_KMS("\n"); - pipe_config->has_dsi_encoder = true; - if (fixed_mode) { intel_fixed_panel_mode(fixed_mode, adjusted_mode); @@ -967,8 +965,6 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, u32 pclk; DRM_DEBUG_KMS("\n"); - pipe_config->has_dsi_encoder = true; - if (IS_BROXTON(dev)) bxt_dsi_get_pipe_config(encoder, pipe_config); -- cgit v1.2.3 From 3f1c928f92a8cdeaca6c2ff7a14dfeb2a5272601 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:08 +0300 Subject: drm/i915: Simplify hdmi_12bpc_possible() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the output_types bitmask there's no need to loop through the encoders anymore when checking for HDMI+non-HDMI cloning. v2: Use output_types bitmask v3: Fix the logic to really check that there are no non-HDMI encoders Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst (v2) Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-11-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_hdmi.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index e94244266b19..4df9f384910c 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1273,33 +1273,15 @@ intel_hdmi_mode_valid(struct drm_connector *connector, static bool hdmi_12bpc_possible(struct intel_crtc_state *crtc_state) { struct drm_device *dev = crtc_state->base.crtc->dev; - struct drm_atomic_state *state; - struct intel_encoder *encoder; - struct drm_connector *connector; - struct drm_connector_state *connector_state; - int count = 0, count_hdmi = 0; - int i; if (HAS_GMCH_DISPLAY(dev)) return false; - state = crtc_state->base.state; - - for_each_connector_in_state(state, connector, connector_state, i) { - if (connector_state->crtc != crtc_state->base.crtc) - continue; - - encoder = to_intel_encoder(connector_state->best_encoder); - - count_hdmi += encoder->type == INTEL_OUTPUT_HDMI; - count++; - } - /* * HDMI 12bpc affects the clocks, so it's only possible * when not cloning with other encoder types. */ - return count_hdmi > 0 && count_hdmi == count; + return crtc_state->output_types == 1 << INTEL_OUTPUT_HDMI; } bool intel_hdmi_compute_config(struct intel_encoder *encoder, -- cgit v1.2.3 From e25148d01d58a7e6a51fc93eea5595c0798f2e9b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Jun 2016 21:57:09 +0300 Subject: drm/i915: Check for invalid cloning earlier during modeset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the encoder cloning check to happen earlier in the modeset. The main benefit will be that the debug output from a failed modeset will be less confusing as output_types can not indicate an invalid configuration during the later computation stages. For instance, what happened to me was kms_setmode was attempting one of its invalid cloning checks during which it asked for DP+VGA cloning on HSW. In this case the DP .compute_config() was executed after the FDI .compute_config() leaving the DP link clock (1.62 in this case) in port_clock, and then later the FDI BW computation tried to use that as the FDI link clock (which should always be 2.7). 1.62 x 2 wasn't enough for the mode it was trying to use, and so it ended up rejecting the modeset, not because of an invalid cloning configuration, but because of supposedly running out of FDI bandwidth. Took me a while to figure out what had actually happened. Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/1466621833-5054-12-git-send-email-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8704355e471a..487ed2165322 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11997,26 +11997,6 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state, return true; } -static bool check_encoder_cloning(struct drm_atomic_state *state, - struct intel_crtc *crtc) -{ - struct intel_encoder *encoder; - struct drm_connector *connector; - struct drm_connector_state *connector_state; - int i; - - for_each_connector_in_state(state, connector, connector_state, i) { - if (connector_state->crtc != &crtc->base) - continue; - - encoder = to_intel_encoder(connector_state->best_encoder); - if (!check_single_encoder_cloning(state, crtc, encoder)) - return false; - } - - return true; -} - static int intel_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state) { @@ -12029,11 +12009,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, int ret; bool mode_changed = needs_modeset(crtc_state); - if (mode_changed && !check_encoder_cloning(state, intel_crtc)) { - DRM_DEBUG_KMS("rejecting invalid cloning configuration\n"); - return -EINVAL; - } - if (mode_changed && !crtc_state->active) pipe_config->update_wm_post = true; @@ -12472,6 +12447,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, encoder = to_intel_encoder(connector_state->best_encoder); + if (!check_single_encoder_cloning(state, to_intel_crtc(crtc), encoder)) { + DRM_DEBUG_KMS("rejecting invalid cloning configuration\n"); + goto fail; + } + /* * Determine output_types before calling the .compute_config() * hooks so that the hooks can use this information safely. -- cgit v1.2.3 From 3485d99e415fadedfeeeb92d12d61e11d143dd21 Mon Sep 17 00:00:00 2001 From: Tim Gore Date: Tue, 5 Jul 2016 10:01:30 +0100 Subject: drm/i915:gen9: implement WaMediaPoolStateCmdInWABB This patch applies WaMediaPoolStateCmdInWABB which fixes a problem with the restoration of thread counts on resuming from RC6. References: HSD#2137167 Signed-off-by: Tim Gore Reviewed-by: Arun Siluvery Signed-off-by: Tvrtko Ursulin Link: http://patchwork.freedesktop.org/patch/msgid/1467709290-5941-1-git-send-email-tim.gore@intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index d47d1a0dbb91..70c699043d0e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1296,6 +1296,31 @@ static int gen9_init_indirectctx_bb(struct intel_engine_cs *engine, wa_ctx_emit(batch, index, 0); wa_ctx_emit(batch, index, 0); } + + /* WaMediaPoolStateCmdInWABB:bxt */ + if (HAS_POOLED_EU(engine->i915)) { + /* + * EU pool configuration is setup along with golden context + * during context initialization. This value depends on + * device type (2x6 or 3x6) and needs to be updated based + * on which subslice is disabled especially for 2x6 + * devices, however it is safe to load default + * configuration of 3x6 device instead of masking off + * corresponding bits because HW ignores bits of a disabled + * subslice and drops down to appropriate config. Please + * see render_state_setup() in i915_gem_render_state.c for + * possible configurations, to avoid duplication they are + * not shown here again. + */ + u32 eu_pool_config = 0x00777000; + wa_ctx_emit(batch, index, GEN9_MEDIA_POOL_STATE); + wa_ctx_emit(batch, index, GEN9_MEDIA_POOL_ENABLE); + wa_ctx_emit(batch, index, eu_pool_config); + wa_ctx_emit(batch, index, 0); + wa_ctx_emit(batch, index, 0); + wa_ctx_emit(batch, index, 0); + } + /* Pad to end of cacheline */ while (index % CACHELINE_DWORDS) wa_ctx_emit(batch, index, MI_NOOP); -- cgit v1.2.3 From 22dea0be50b2eb0bafd3c82e1fb080113e0c889e Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 1 Jul 2016 17:07:12 -0700 Subject: drm/i915: Introduce Kabypoint PCH for Kabylake H/DT. Some Kabylake SKUs are going to use Kabypoint PCH. It is mainly for Halo and DT ones. >From our specs it doesn't seem that KBP brings any change on the display south engine. So let's consider this as a continuation of SunrisePoint, i.e., SPT+. Since it is easy to get confused by a letter change: KBL = Kabylake - CPU/GPU codename. KBP = Kabypoint - PCH codename. Signed-off-by: Rodrigo Vivi Reviewed-by: Ander Conselvan de Oliveira Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96826 Link: http://patchwork.freedesktop.org/patch/msgid/1467418032-15167-1-git-send-email-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_drv.c | 4 ++++ drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/i915_irq.c | 4 ++-- drivers/gpu/drm/i915/intel_panel.c | 3 ++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 694edac2c703..b9a811750ca8 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -204,6 +204,10 @@ static void intel_detect_pch(struct drm_device *dev) DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n"); WARN_ON(!IS_SKYLAKE(dev) && !IS_KABYLAKE(dev)); + } else if (id == INTEL_PCH_KBP_DEVICE_ID_TYPE) { + dev_priv->pch_type = PCH_KBP; + DRM_DEBUG_KMS("Found KabyPoint PCH\n"); + WARN_ON(!IS_KABYLAKE(dev)); } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) || (id == INTEL_PCH_P3X_DEVICE_ID_TYPE) || ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) && diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d2c60992a508..a46b57579da1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1027,6 +1027,7 @@ enum intel_pch { PCH_CPT, /* Cougarpoint PCH */ PCH_LPT, /* Lynxpoint PCH */ PCH_SPT, /* Sunrisepoint PCH */ + PCH_KBP, /* Kabypoint PCH */ PCH_NOP, }; @@ -2883,11 +2884,13 @@ struct drm_i915_cmd_table { #define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 +#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA200 #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 #define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 #define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type) +#define HAS_PCH_KBP(dev) (INTEL_PCH_TYPE(dev) == PCH_KBP) #define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT) #define HAS_PCH_LPT(dev) (INTEL_PCH_TYPE(dev) == PCH_LPT) #define HAS_PCH_LPT_LP(dev) (__I915__(dev)->pch_id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a69a5fc75bd6..1c2aec392412 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2425,7 +2425,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) I915_WRITE(SDEIIR, iir); ret = IRQ_HANDLED; - if (HAS_PCH_SPT(dev_priv)) + if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv)) spt_irq_handler(dev_priv, iir); else cpt_irq_handler(dev_priv, iir); @@ -4588,7 +4588,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) dev->driver->disable_vblank = gen8_disable_vblank; if (IS_BROXTON(dev)) dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; - else if (HAS_PCH_SPT(dev)) + else if (HAS_PCH_SPT(dev) || HAS_PCH_KBP(dev)) dev_priv->display.hpd_irq_setup = spt_hpd_irq_setup; else dev_priv->display.hpd_irq_setup = ilk_hpd_irq_setup; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 295f0ddca718..96c65d77e886 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1731,7 +1731,8 @@ intel_panel_init_backlight_funcs(struct intel_panel *panel) panel->backlight.set = bxt_set_backlight; panel->backlight.get = bxt_get_backlight; panel->backlight.hz_to_pwm = bxt_hz_to_pwm; - } else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_SPT(dev_priv)) { + } else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_SPT(dev_priv) || + HAS_PCH_KBP(dev_priv)) { panel->backlight.setup = lpt_setup_backlight; panel->backlight.enable = lpt_enable_backlight; panel->backlight.disable = lpt_disable_backlight; -- cgit v1.2.3 From 48f112fed3b07858f1b3a78548d23320fb96747b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Jun 2016 14:07:14 +0100 Subject: drm/i915: Fill unused GGTT with scratch pages for VT-d One of the numerous VT-d workarounds we require is that the display hardware reads past the end of the buffer triggering VT-d faults. This is acknowledged in the code as being safe "since we fill the unused portions of the GGTT with the scratch page". Alas, that is no longer always true and so we trigger DMAR read faults. Skylake also requires another workaround to avoid mixing VT-d and unpopulated PTE, and so there we also need to ensure we fill unused entries with the scratch page. Reported-by: Mike Lothian Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96584 Fixes: f7770bfd9fd2 ("drm/i915: Skip clearing the GGTT on full-ppgtt systems") Signed-off-by: Chris Wilson Cc: David Weinehall Cc: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/1466773634-8106-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: David Weinehall --- drivers/gpu/drm/i915/i915_drv.h | 9 +++++++++ drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- drivers/gpu/drm/i915/intel_display.c | 11 +---------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a46b57579da1..4478cc852489 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2912,6 +2912,15 @@ struct drm_i915_cmd_table { #include "i915_trace.h" +static inline bool intel_scanout_needs_vtd_wa(struct drm_i915_private *dev_priv) +{ +#ifdef CONFIG_INTEL_IOMMU + if (INTEL_GEN(dev_priv) >= 6 && intel_iommu_gfx_mapped) + return true; +#endif + return false; +} + extern int i915_suspend_switcheroo(struct drm_device *dev, pm_message_t state); extern int i915_resume_switcheroo(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 365fe65950e1..10f1e32767e6 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3119,7 +3119,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) ggtt->base.unbind_vma = ggtt_unbind_vma; ggtt->base.insert_page = gen8_ggtt_insert_page; ggtt->base.clear_range = nop_clear_range; - if (!USES_FULL_PPGTT(dev_priv)) + if (!USES_FULL_PPGTT(dev_priv) || intel_scanout_needs_vtd_wa(dev_priv)) ggtt->base.clear_range = gen8_ggtt_clear_range; ggtt->base.insert_entries = gen8_ggtt_insert_entries; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 487ed2165322..be3b2cab2640 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2046,15 +2046,6 @@ static void intel_disable_pipe(struct intel_crtc *crtc) intel_wait_for_pipe_off(crtc); } -static bool need_vtd_wa(struct drm_device *dev) -{ -#ifdef CONFIG_INTEL_IOMMU - if (INTEL_INFO(dev)->gen >= 6 && intel_iommu_gfx_mapped) - return true; -#endif - return false; -} - static unsigned int intel_tile_size(const struct drm_i915_private *dev_priv) { return IS_GEN2(dev_priv) ? 2048 : 4096; @@ -2236,7 +2227,7 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, * we should always have valid PTE following the scanout preventing * the VT-d warning. */ - if (need_vtd_wa(dev) && alignment < 256 * 1024) + if (intel_scanout_needs_vtd_wa(dev_priv) && alignment < 256 * 1024) alignment = 256 * 1024; /* -- cgit v1.2.3 From 5bc1e9e95dcd44f60a67168e0f09ab50958066c9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 Jul 2016 09:49:07 +0100 Subject: drm/i915: Select X86_MSR for igt igt/pm_rpm depends upon /dev/*/msr so automatically select it when enabling i915 debugging. Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1468054147-9821-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/Kconfig.debug | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index 43400adc95db..3309b82652af 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -19,6 +19,7 @@ config DRM_I915_DEBUG bool "Enable additional driver debugging" depends on DRM_I915 select PREEMPT_COUNT + select X86_MSR # used by igt/pm_rpm default n help Choose this option to turn on extra driver debugging that may affect -- cgit v1.2.3 From c31966a1bd09d46b079f0656574e53782c237994 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 Jul 2016 11:22:57 +0100 Subject: drm/i915: Select DRM_VGEM for igt igt/prime_vgem (and others) depends upon VGEM so automatically select it when enabling i915 debugging. Signed-off-by: Chris Wilson Link: http://patchwork.freedesktop.org/patch/msgid/1468059777-10205-1-git-send-email-chris@chris-wilson.co.uk Reviewed-by: Matthew Auld --- drivers/gpu/drm/i915/Kconfig.debug | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index 3309b82652af..cee87bfd10c4 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -20,6 +20,7 @@ config DRM_I915_DEBUG depends on DRM_I915 select PREEMPT_COUNT select X86_MSR # used by igt/pm_rpm + select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks) default n help Choose this option to turn on extra driver debugging that may affect -- cgit v1.2.3 From 0b2c0582f1570bfc95aa9ac1cd340a215d8e8335 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Jul 2016 09:18:31 +0200 Subject: drm/i915: Update DRIVER_DATE to 20160711 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4478cc852489..03e1bfaa5a41 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -69,7 +69,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20160620" +#define DRIVER_DATE "20160711" #undef WARN_ON /* Many gcc seem to no see through this and fall over :( */ -- cgit v1.2.3