From 4c2e0990ade3251c9b5770aa8f06b06375b66f9f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 5 Jun 2014 16:22:16 +0200 Subject: drm/i915: Fixup global gtt cleanup The global gtt is setup up in 2 parts, so we need to be careful with the cleanup. For consistency shovel it all into the ->cleanup callback, like with ppgtt. Noticed because it blew up in the out_gtt: cleanup code while fiddling with the vgacon code. Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 ---- drivers/gpu/drm/i915/i915_gem_gtt.c | 9 ++++++++- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index b9159ade5e85..27fe65ac5940 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1386,7 +1386,6 @@ cleanup_gem: i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); WARN_ON(dev_priv->mm.aliasing_ppgtt); - drm_mm_takedown(&dev_priv->gtt.base.mm); cleanup_irq: drm_irq_uninstall(dev); cleanup_gem_stolen: @@ -1756,8 +1755,6 @@ out_mtrrfree: arch_phys_wc_del(dev_priv->gtt.mtrr); io_mapping_free(dev_priv->gtt.mappable); out_gtt: - list_del(&dev_priv->gtt.base.global_link); - drm_mm_takedown(&dev_priv->gtt.base.mm); dev_priv->gtt.base.cleanup(&dev_priv->gtt.base); out_regs: intel_uncore_fini(dev); @@ -1846,7 +1843,6 @@ int i915_driver_unload(struct drm_device *dev) i915_free_hws(dev); } - list_del(&dev_priv->gtt.base.global_link); WARN_ON(!list_empty(&dev_priv->vm_list)); drm_vblank_cleanup(dev); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 931b906f292a..41e864ec5632 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1985,7 +1985,10 @@ static void gen6_gmch_remove(struct i915_address_space *vm) struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base); - drm_mm_takedown(&vm->mm); + if (drm_mm_initialized(&vm->mm)) { + drm_mm_takedown(&vm->mm); + list_del(&vm->global_link); + } iounmap(gtt->gsm); teardown_scratch_page(vm->dev); } @@ -2018,6 +2021,10 @@ static int i915_gmch_probe(struct drm_device *dev, static void i915_gmch_remove(struct i915_address_space *vm) { + if (drm_mm_initialized(&vm->mm)) { + drm_mm_takedown(&vm->mm); + list_del(&vm->global_link); + } intel_gmch_remove(); } -- cgit v1.2.2 From a4de05268e674e8ed31df6348269e22d6c6a1803 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 5 Jun 2014 16:20:46 +0200 Subject: drm/i915: Kick out vga console Touching the VGA resources on an IVB EFI machine causes hard hangs when we then kick out the efifb. Ouch. Apparently this also prevents unclaimed register errors on hsw and hard machine hangs on my i855gm when trying to unbind fbcon. Also, we want this to make I915_FBDEV=n safe. v2: Rebase and pimp commit message. v3: We also need to unregister the vga console, otherwise the unbind of the fb console before module unload might resurrect it again. v4: Ignore errors when the vga console is already unregistered - this can happen when e.g. reloading i915.ko. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67813 Cc: David Herrmann Cc: Jean-Christophe Plagniol-Villard Cc: Tomi Valkeinen Cc: linux-fbdev@vger.kernel.org Cc: Jani Nikula Signed-off-by: Chris Wilson (v1) Reviewed-by: David Herrmann Acked-by: Tomi Valkeinen Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 43 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 27fe65ac5940..bcb66ddd649e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -36,6 +36,8 @@ #include "i915_drv.h" #include "i915_trace.h" #include +#include +#include #include #include #include @@ -1449,6 +1451,38 @@ static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) } #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; + + DRM_INFO("Replacing VGA console driver\n"); + + console_lock(); + 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; @@ -1622,8 +1656,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (ret) goto out_regs; - if (drm_core_check_feature(dev, DRIVER_MODESET)) + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = i915_kick_out_vgacon(dev_priv); + if (ret) { + DRM_ERROR("failed to remove conflicting VGA console\n"); + goto out_gtt; + } + i915_kick_out_firmware_fb(dev_priv); + } pci_set_master(dev->pdev); -- cgit v1.2.2 From 0368920e51ae0cded0eb518c340a4dd17764d461 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 6 Jun 2014 10:37:11 +0100 Subject: drm/i915: Disable FBC by default also on Haswell and later It causes black screen on bootup and is approximately 100x slower than running with FBC disabled, so the GPU runs at a high frequency for much longer - completely contrary to the power saving claims. It also still has mutex deadlocks in multi-head scenarios, which can lead to a system/X lockup. These bugs were known before FBC was enabled by default on Haswell and still have not been fixed. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79716 Reported-and-tested-by: Jon Kristensen Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org [Jani: update subject to reflect the actual change] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_pm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d1e53abec1b5..7e2db9abd810 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -511,8 +511,7 @@ void intel_update_fbc(struct drm_device *dev) obj = intel_fb->obj; adjusted_mode = &intel_crtc->config.adjusted_mode; - if (i915.enable_fbc < 0 && - INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) { + if (i915.enable_fbc < 0) { if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT)) DRM_DEBUG_KMS("disabled per chip default\n"); goto out_disable; -- cgit v1.2.2 From 2b85886a5457f5c5dbcd32edbd4e6bba0f4e8678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 9 Jun 2014 16:20:46 +0300 Subject: drm/i915: Avoid div-by-zero when pixel_multiplier is zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On certain platforms pixel_multiplier is read out in .get_pipe_config(), but it also gets used to calculate the pixel clock in intel_sdvo_get_config(). If the pipe is disable but some SDVO outputs are active, we may end up dividing by zero in intel_sdvo_get_config(). To avoid the problem simply check for zero pixel_multiplier and skip the division. Another attempt at fixing this involved populating pixel_multiplier to 1 even for disabled pipes, but that triggered a WARN because SDVO_CMD_GET_CLOCK_RATE_MULT command failed and thus encoder_pixel_multiplier was left at zero and didn't match pipe_config->pixel_multiplier. The "divide by pixel_multiplier" operation got introduced here: commit 18442d08786472c63a0a80c27f92b033dffc26de Author: Ville Syrjälä Date: Fri Sep 13 16:00:08 2013 +0300 drm/i915: Fix port_clock and adjusted_mode.clock readout all over and it has caused a regression on certain machines since they would hit the div-by-zero during resume. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76520 Cc: # 3.13+ Tested-by: Tim Richardson Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_sdvo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 6a4d5bc17697..20375cc7f82d 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1385,7 +1385,9 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, >> SDVO_PORT_MULTIPLY_SHIFT) + 1; } - dotclock = pipe_config->port_clock / pipe_config->pixel_multiplier; + dotclock = pipe_config->port_clock; + if (pipe_config->pixel_multiplier) + dotclock /= pipe_config->pixel_multiplier; if (HAS_PCH_SPLIT(dev)) ironlake_check_encoder_dotclock(pipe_config, dotclock); -- cgit v1.2.2 From 2e7eeeb59a92d09144fdb7d2dc1af77a10a7945b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 9 Jun 2014 18:24:34 +0300 Subject: drm/i915: set backlight duty cycle after backlight enable for gen4 For reasons I can't claim to fully understand gen4 seems to require backlight duty cycle setting after the backlight has been enabled, or else black screen follows. I don't have documentation for the correct sequence on gen4 either. Confirmed on Dell Latitude D630 and MacBook4,1. This fixes a regression introduced by commit b35684b8fa94e04f55fd38bf672b737741d2f9e2 Author: Jani Nikula Date: Thu Nov 14 12:13:41 2013 +0200 drm/i915: do full backlight setup at enable time Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=75791 Reported-and-tested-by: mcy@lm7.fr Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79423 Reported-and-tested-by: Marc Milgram Cc: Stable # 3.14+ Acked-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_panel.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 5e6c888b4928..38a98570d10c 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -798,9 +798,6 @@ static void i965_enable_backlight(struct intel_connector *connector) ctl = freq << 16; I915_WRITE(BLC_PWM_CTL, ctl); - /* XXX: combine this into above write? */ - intel_panel_actually_set_backlight(connector, panel->backlight.level); - ctl2 = BLM_PIPE(pipe); if (panel->backlight.combination_mode) ctl2 |= BLM_COMBINATION_MODE; @@ -809,6 +806,8 @@ static void i965_enable_backlight(struct intel_connector *connector) I915_WRITE(BLC_PWM_CTL2, ctl2); POSTING_READ(BLC_PWM_CTL2); I915_WRITE(BLC_PWM_CTL2, ctl2 | BLM_PWM_ENABLE); + + intel_panel_actually_set_backlight(connector, panel->backlight.level); } static void vlv_enable_backlight(struct intel_connector *connector) -- cgit v1.2.2 From eee73b46261325eb140d899b5371f49b02d88f63 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 10 Jun 2014 12:09:29 +0100 Subject: drm/i95: Initialize active ring->pid to -1 Otherwise we print out spurious processes on unused rings in the error state. Signed-off-by: Chris Wilson Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gpu_error.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 87ec60e181a7..66cf41765bf9 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -888,6 +888,8 @@ static void i915_gem_record_rings(struct drm_device *dev, for (i = 0; i < I915_NUM_RINGS; i++) { struct intel_engine_cs *ring = &dev_priv->ring[i]; + error->ring[i].pid = -1; + if (ring->dev == NULL) continue; @@ -895,7 +897,6 @@ static void i915_gem_record_rings(struct drm_device *dev, i915_record_ring_state(dev, ring, &error->ring[i]); - error->ring[i].pid = -1; request = i915_gem_find_active_request(ring); if (request) { /* We need to copy these to an anonymous buffer -- cgit v1.2.2 From 4be173813e57c7298103a83155c2391b5b167b4c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 6 Jun 2014 10:22:29 +0100 Subject: drm/i915: Reorder semaphore deadlock check If a semaphore is waiting on another ring, which in turn happens to be waiting on the first ring, but that second semaphore has been signalled, we will be able to kick the second ring and so can treat the first ring as a valid WAIT and not as HUNG. v2: Be paranoid and cap the potential recursion depth whilst visiting the semaphore signallers. (Mika) References: https://bugs.freedesktop.org/show_bug.cgi?id=54226 References: https://bugs.freedesktop.org/show_bug.cgi?id=75502 Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: stable@vger.kernel.org Reviewed-by: Mika Kuoppala Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_irq.c | 18 ++++++++++++++---- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index cf288a95347c..69aaa1100986 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2847,10 +2847,14 @@ static int semaphore_passed(struct intel_engine_cs *ring) struct intel_engine_cs *signaller; u32 seqno, ctl; - ring->hangcheck.deadlock = true; + ring->hangcheck.deadlock++; signaller = semaphore_waits_for(ring, &seqno); - if (signaller == NULL || signaller->hangcheck.deadlock) + if (signaller == NULL) + return -1; + + /* Prevent pathological recursion due to driver bugs */ + if (signaller->hangcheck.deadlock >= I915_NUM_RINGS) return -1; /* cursory check for an unkickable deadlock */ @@ -2858,7 +2862,13 @@ static int semaphore_passed(struct intel_engine_cs *ring) if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0) return -1; - return i915_seqno_passed(signaller->get_seqno(signaller, false), seqno); + if (i915_seqno_passed(signaller->get_seqno(signaller, false), seqno)) + return 1; + + if (signaller->hangcheck.deadlock) + return -1; + + return 0; } static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) @@ -2867,7 +2877,7 @@ static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) int i; for_each_ring(ring, dev_priv, i) - ring->hangcheck.deadlock = false; + ring->hangcheck.deadlock = 0; } static enum intel_ring_hangcheck_action diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 910c83cf7d44..e72017bdcd7f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -55,7 +55,7 @@ struct intel_ring_hangcheck { u32 seqno; int score; enum intel_ring_hangcheck_action action; - bool deadlock; + int deadlock; }; struct intel_ringbuffer { -- cgit v1.2.2 From 329ff963fd4c1356af66b878b11460388cb5f5dd Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 6 Jun 2014 14:04:37 +0300 Subject: drm/i915: fix possible refcount leak when resetting forcewake If the timer putting the last forcewake refcount was pending and we canceled it, we'll leak the corresponding forcewake and RPM references. v2: - do the ptr casting at the caller instead of adding a separate helper for this (Chris) Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_uncore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 79cba593df0d..4f6fef7ac069 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -320,7 +320,8 @@ static void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long irqflags; - del_timer_sync(&dev_priv->uncore.force_wake_timer); + if (del_timer_sync(&dev_priv->uncore.force_wake_timer)) + gen6_force_wake_timer((unsigned long)dev_priv); /* Hold uncore.lock across reset to prevent any register access * with forcewake not set correctly -- cgit v1.2.2 From 223a6f2b975ab35d93270ea1d4fb6e0ac6b27fe6 Mon Sep 17 00:00:00 2001 From: Tom O'Rourke Date: Tue, 10 Jun 2014 16:26:34 -0700 Subject: drm/i915/bdw: remove erroneous chv specific workarounds from bdw code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct a merge mishap in commit e4443e459ccf43f2c139358400365fd6a839d40d Author: Ville Syrjälä Date: Wed Apr 9 13:28:41 2014 +0300 drm/i915/chv: Add a bunch of pre production workarounds Remove the the chv specific workarounds from bdw code, specifically gen8_enable_rps(). Signed-off-by: Tom O'Rourke Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter [Jani: extract hunk #1 for 3.16 from Tom's patch, clarify commit message] Signed-off-by: Jani Nikula --- All, I intend to push this to drm-intel-fixes, any objections? Jani. --- drivers/gpu/drm/i915/intel_pm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7e2db9abd810..769caea97c21 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3505,15 +3505,11 @@ static void gen8_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); - /* WaDisablePwrmtrEvent:chv (pre-production hw) */ - I915_WRITE(0xA80C, I915_READ(0xA80C) & 0x00ffffff); - I915_WRITE(0xA810, I915_READ(0xA810) & 0xffffff00); - /* 5: Enable RPS */ I915_WRITE(GEN6_RP_CONTROL, GEN6_RP_MEDIA_TURBO | GEN6_RP_MEDIA_HW_NORMAL_MODE | - GEN6_RP_MEDIA_IS_GFX | /* WaSetMaskForGfxBusyness:chv (pre-production hw ?) */ + GEN6_RP_MEDIA_IS_GFX | GEN6_RP_ENABLE | GEN6_RP_UP_BUSY_AVG | GEN6_RP_DOWN_IDLE_AVG); -- cgit v1.2.2 From 74b0c2d75fb4cc89173944e6d8f9eb47aca0c343 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 13 Jun 2014 15:14:34 +0200 Subject: drm/i915, HD-audio: Don't continue probing when nomodeset is given When a machine is booted with nomodeset option, i915 driver skips the whole initialization. Meanwhile, HD-audio tries to bind wth i915 just by request_symbol() without knowing that the initialization was skipped, and eventually it hits WARN_ON() in i915_request_power_well() and i915_release_power_well() wrongly but still continues probing, even though it doesn't work at all. In this patch, both functions are changed to return an error in case of uninitialized state instead of WARN_ON(), so that HD-audio driver can give up HDMI controller initialization at the right time. Acked-by: Daniel Vetter Cc: [3.15] Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/intel_pm.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d1e53abec1b5..6463f0201cf2 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6024,30 +6024,32 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, static struct i915_power_domains *hsw_pwr; /* Display audio driver power well request */ -void i915_request_power_well(void) +int i915_request_power_well(void) { struct drm_i915_private *dev_priv; - if (WARN_ON(!hsw_pwr)) - return; + if (!hsw_pwr) + return -ENODEV; dev_priv = container_of(hsw_pwr, struct drm_i915_private, power_domains); intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); + return 0; } EXPORT_SYMBOL_GPL(i915_request_power_well); /* Display audio driver power well release */ -void i915_release_power_well(void) +int i915_release_power_well(void) { struct drm_i915_private *dev_priv; - if (WARN_ON(!hsw_pwr)) - return; + if (!hsw_pwr) + return -ENODEV; dev_priv = container_of(hsw_pwr, struct drm_i915_private, power_domains); intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO); + return 0; } EXPORT_SYMBOL_GPL(i915_release_power_well); -- cgit v1.2.2 From bfafe93a1cd466ef318b7e5f6c65f59aee147791 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 5 Jun 2014 20:31:47 +0300 Subject: drm/i915: cache hw power well enabled state Jesse noticed that the punit communication needed to query the VLV power well status can cause substantial delays. Since we can query the state frequently, for example during I2C transfers, maintain a cached version of the HW state to get rid of this delay. This fixes at least one reported regression where boot time increased by ~4 seconds due to frequent power well state queries on VLV during eDP EDID read. This regression has been introduced in commit bb4932c4f17b68f34645ffbcf845e4c29d17290b Author: Imre Deak Date: Mon Apr 14 20:24:33 2014 +0300 drm/i915: vlv: check port power domain instead of only D0 for eDP VDD on Reported-by: Jesse Barnes Signed-off-by: Imre Deak Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 6 +++--- drivers/gpu/drm/i915/intel_drv.h | 4 ++-- drivers/gpu/drm/i915/intel_pm.c | 37 +++++++++++++++--------------------- 4 files changed, 22 insertions(+), 27 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 49414d30e8d4..a47fbf60b781 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -977,6 +977,8 @@ struct i915_power_well { bool always_on; /* power well enable/disable usage count */ int count; + /* cached hw enabled state */ + bool hw_enabled; unsigned long domains; unsigned long data; const struct i915_power_well_ops *ops; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index efd3cf50cb0f..9188fede99ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12411,8 +12411,8 @@ intel_display_capture_error_state(struct drm_device *dev) for_each_pipe(i) { error->pipe[i].power_domain_on = - intel_display_power_enabled_sw(dev_priv, - POWER_DOMAIN_PIPE(i)); + intel_display_power_enabled_unlocked(dev_priv, + POWER_DOMAIN_PIPE(i)); if (!error->pipe[i].power_domain_on) continue; @@ -12447,7 +12447,7 @@ intel_display_capture_error_state(struct drm_device *dev) enum transcoder cpu_transcoder = transcoders[i]; error->transcoder[i].power_domain_on = - intel_display_power_enabled_sw(dev_priv, + intel_display_power_enabled_unlocked(dev_priv, POWER_DOMAIN_TRANSCODER(cpu_transcoder)); if (!error->transcoder[i].power_domain_on) continue; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bda0ae3d80cc..eaa27ee9e367 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -950,8 +950,8 @@ int intel_power_domains_init(struct drm_i915_private *); void intel_power_domains_remove(struct drm_i915_private *); bool intel_display_power_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); -bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain); +bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain); void intel_display_power_get(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); void intel_display_power_put(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 54242e4f6f4c..9ad0c6afc487 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5603,8 +5603,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); } -bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, - enum intel_display_power_domain domain) +bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv, + enum intel_display_power_domain domain) { struct i915_power_domains *power_domains; struct i915_power_well *power_well; @@ -5615,16 +5615,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv, return false; power_domains = &dev_priv->power_domains; + is_enabled = true; + for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { if (power_well->always_on) continue; - if (!power_well->count) { + if (!power_well->hw_enabled) { is_enabled = false; break; } } + return is_enabled; } @@ -5632,30 +5635,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain) { struct i915_power_domains *power_domains; - struct i915_power_well *power_well; - bool is_enabled; - int i; - - if (dev_priv->pm.suspended) - return false; + bool ret; power_domains = &dev_priv->power_domains; - is_enabled = true; - mutex_lock(&power_domains->lock); - for_each_power_well_rev(i, power_well, BIT(domain), power_domains) { - if (power_well->always_on) - continue; - - if (!power_well->ops->is_enabled(dev_priv, power_well)) { - is_enabled = false; - break; - } - } + ret = intel_display_power_enabled_unlocked(dev_priv, domain); mutex_unlock(&power_domains->lock); - return is_enabled; + return ret; } /* @@ -5976,6 +5964,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, if (!power_well->count++) { DRM_DEBUG_KMS("enabling %s\n", power_well->name); power_well->ops->enable(dev_priv, power_well); + power_well->hw_enabled = true; } check_power_well_state(dev_priv, power_well); @@ -6005,6 +5994,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, if (!--power_well->count && i915.disable_power_well) { DRM_DEBUG_KMS("disabling %s\n", power_well->name); + power_well->hw_enabled = false; power_well->ops->disable(dev_priv, power_well); } @@ -6267,8 +6257,11 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv) int i; mutex_lock(&power_domains->lock); - for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) + for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) { power_well->ops->sync_hw(dev_priv, power_well); + power_well->hw_enabled = power_well->ops->is_enabled(dev_priv, + power_well); + } mutex_unlock(&power_domains->lock); } -- cgit v1.2.2 From 56c4b63aaf4c2cd91966b2a5e69e5367bea60bbe Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 17 Jun 2014 15:47:05 +0300 Subject: drm/i915: default to having backlight if VBT not available Apparently there are Apple laptops with magic smoke for a VBIOS, which we fail to find and use. Default to having and setting up backlight in this case. This fixes a regression introduced by commit c675949ec58ca50d5a3ae3c757892f1560f6e896 Author: Jani Nikula Date: Wed Apr 9 11:31:37 2014 +0300 drm/i915: do not setup backlight if not available according to VBT Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=77831 Reported-and-tested-by: Matteo Cypriani Cc: stable@vger.kernel.org # 3.15+ Reviewed-by: Imre Deak Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_bios.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 1ee98f121a00..827498e081df 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -315,9 +315,6 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) const struct bdb_lfp_backlight_data *backlight_data; const struct bdb_lfp_backlight_data_entry *entry; - /* Err to enabling backlight if no backlight block. */ - dev_priv->vbt.backlight.present = true; - backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); if (!backlight_data) return; @@ -1088,6 +1085,9 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) dev_priv->vbt.crt_ddc_pin = GMBUS_PORT_VGADDC; + /* Default to having backlight */ + dev_priv->vbt.backlight.present = true; + /* LFP panel data */ dev_priv->vbt.lvds_dither = 1; dev_priv->vbt.lvds_vbt = 0; -- cgit v1.2.2 From 967ab6b177ee7111383585639e375d9f67638010 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 30 May 2014 14:16:30 +0100 Subject: drm/i915: Only mark the ctx as initialised after a SET_CONTEXT operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fallout from commit 46470fc932ac8a0e8317a220b3f4ea4ed903338e Author: Mika Kuoppala Date: Wed May 21 19:01:06 2014 +0300 drm/i915: Add null state batch to active list undid the earlier fix of only marking the ctx as initialised after it is saved by the hardware during a SET_CONTEXT operation: commit ad1d219974a3d13412268525309c5892f6779ae9 Author: Ben Widawsky Date: Sat Dec 28 13:31:49 2013 -0800 drm/i915: set ctx->initialized only after RCS Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Damien Lespiau Cc: Mika Kuoppala Cc: Ben Widawsky Reviewed-by: Daniel Vetter Reviewed-by: Ben Widawsky [Jani: add reference to the earlier fix in the commit messsage.] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_context.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 3ffe308d5893..a5ddf3bce9c3 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -598,6 +598,7 @@ static int do_switch(struct intel_engine_cs *ring, struct intel_context *from = ring->last_context; struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to); u32 hw_flags = 0; + bool uninitialized = false; int ret, i; if (from != NULL && ring == &dev_priv->ring[RCS]) { @@ -696,19 +697,20 @@ static int do_switch(struct intel_engine_cs *ring, i915_gem_context_unreference(from); } + uninitialized = !to->is_initialized && from == NULL; + to->is_initialized = true; + done: i915_gem_context_reference(to); ring->last_context = to; to->last_ring = ring; - if (ring->id == RCS && !to->is_initialized && from == NULL) { + if (uninitialized) { ret = i915_gem_render_state_init(ring); if (ret) DRM_ERROR("init render state: %d\n", ret); } - to->is_initialized = true; - return 0; unpin_out: -- cgit v1.2.2 From 5b5ffff0d25060ab0e21fa0f6cd16428e87bf1ea Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Jun 2014 09:56:24 +0100 Subject: drm/i915: Hold the table lock whilst walking the file's idr and counting the objects in debugfs Fixes an issue whereby we may race with the table updates (before the core takes the struct_mutex) and so risk dereferencing a stale pointer in the iterator for /debugfs/.../i915_gem_objects. For example, [ 1524.757545] BUG: unable to handle kernel paging request at f53af748 [ 1524.757572] IP: [] per_file_stats+0x12/0x100 [ 1524.757599] *pdpt = 0000000001b13001 *pde = 00000000379fb067 *pte = 80000000353af060 [ 1524.757621] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC [ 1524.757637] Modules linked in: ctr ccm arc4 ath9k ath9k_common ath9k_hw ath snd_hda_codec_conexant mac80211 snd_hda_codec_generic snd_hda_intel snd_hda_controller snd_hda_codec bnep snd_hwdep rfcomm snd_pcm gpio_ich dell_wmi sparse_keymap snd_seq_midi hid_multitouch uvcvideo snd_seq_midi_event dell_laptop snd_rawmidi dcdbas snd_seq videobuf2_vmalloc videobuf2_memops videobuf2_core usbhid videodev snd_seq_device coretemp snd_timer hid joydev kvm_intel cfg80211 ath3k kvm btusb bluetooth serio_raw snd microcode soundcore lpc_ich wmi mac_hid parport_pc ppdev lp parport psmouse ahci libahci [ 1524.757825] CPU: 3 PID: 1911 Comm: intel-gpu-overl Tainted: G W OE 3.15.0-rc3+ #96 [ 1524.757840] Hardware name: Dell Inc. Inspiron 1090/Inspiron 1090, BIOS A06 08/23/2011 [ 1524.757855] task: f52f36c0 ti: f4cbc000 task.ti: f4cbc000 [ 1524.757869] EIP: 0060:[] EFLAGS: 00210202 CPU: 3 [ 1524.757884] EIP is at per_file_stats+0x12/0x100 [ 1524.757896] EAX: 0000002d EBX: 00000000 ECX: f4cbdefc EDX: f53af700 [ 1524.757909] ESI: c1406970 EDI: f53af700 EBP: f4cbde6c ESP: f4cbde5c [ 1524.757922] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [ 1524.757934] CR0: 80050033 CR2: f53af748 CR3: 356af000 CR4: 000007f0 [ 1524.757945] Stack: [ 1524.757957] f4cbdefc 00000000 c1406970 f53af700 f4cbdea8 c12e5f15 f4cbdefc c1406970 [ 1524.757993] 0000ffff f4cbde90 0000002d f5dc5cd0 e4e80438 c1181d59 f4cbded8 f4d89900 [ 1524.758027] f5631b40 e5131074 c1903f37 f4cbdf28 c14068e6 f52648a0 c1927748 c1903f37 [ 1524.758062] Call Trace: [ 1524.758084] [] ? i915_gem_object_info+0x510/0x510 [ 1524.758106] [] idr_for_each+0xa5/0x100 [ 1524.758126] [] ? i915_gem_object_info+0x510/0x510 [ 1524.758148] [] ? seq_vprintf+0x29/0x50 [ 1524.758168] [] i915_gem_object_info+0x486/0x510 [ 1524.758189] [] seq_read+0xd6/0x380 [ 1524.758208] [] ? final_putname+0x1d/0x40 [ 1524.758227] [] ? seq_hlist_next_percpu+0x90/0x90 [ 1524.758246] [] vfs_read+0x82/0x150 [ 1524.758265] [] SyS_read+0x46/0x90 [ 1524.758285] [] sysenter_do_call+0x12/0x22 [ 1524.758298] Code: f5 8f 2a 00 83 c4 6c 31 c0 5b 5e 5f 5d c3 8d 74 26 00 8d bc 27 00 00 00 00 55 89 e5 57 56 53 83 ec 04 3e 8d 74 26 00 83 41 04 01 <8b> 42 48 01 41 08 8b 42 4c 89 d7 85 c0 75 07 8b 42 60 85 c0 74 [ 1524.758461] EIP: [] per_file_stats+0x12/0x100 SS:ESP 0068:f4cbde5c [ 1524.758485] CR2: 00000000f53af748 Reported-by: Sam Jansen Signed-off-by: Chris Wilson Cc: Sam Jansen Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_debugfs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 601caa88c092..b8c689202c40 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -446,7 +446,9 @@ static int i915_gem_object_info(struct seq_file *m, void* data) memset(&stats, 0, sizeof(stats)); stats.file_priv = file->driver_priv; + spin_lock(&file->table_lock); idr_for_each(&file->object_idr, per_file_stats, &stats); + spin_unlock(&file->table_lock); /* * Although we have a valid reference on file->pid, that does * not guarantee that the task_struct who called get_pid() is -- cgit v1.2.2 From 8525a235c96a548873c6c5644f50df32b31f04c6 Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Wed, 25 Jun 2014 12:20:39 +0530 Subject: drm/i915: vlv_prepare_pll is only needed in case of non DSI interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For MIPI, DSI PLL is configured separately in vlv_configure_dsi_pll during the DSI enable sequence Causing WARN dump otherwise in dpio_reads v2: Add IS_CHERRYVIEW check as suggested by Ville Signed-off-by: Shobhit Kumar Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9188fede99ef..5f285fba4e41 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4564,7 +4564,10 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->active) return; - vlv_prepare_pll(intel_crtc); + is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); + + if (!is_dsi && !IS_CHERRYVIEW(dev)) + vlv_prepare_pll(intel_crtc); /* Set up the display plane register */ dspcntr = DISPPLANE_GAMMA_ENABLE; @@ -4598,8 +4601,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) if (encoder->pre_pll_enable) encoder->pre_pll_enable(encoder); - is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); - if (!is_dsi) { if (IS_CHERRYVIEW(dev)) chv_enable_pll(intel_crtc); -- cgit v1.2.2 From 33c3b0d19184cb11bfe8cf8e552918650f81f767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 24 Jun 2014 13:59:28 +0300 Subject: drm/i915: Wait for vblank after enabling the primary plane on BDW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BDW signals the flip done interrupt immediately after the DSPSURF write when the plane is disabled. This is true even if we've already armed DSPCNTR to enable the plane at the next vblank. This causes major problems for our page flip code which relies on the flip done interrupts happening at vblank time. So what happens is that we enable the plane, and immediately allow userspace to submit a page flip. If the plane is still in the process of being enabled when the page flip is issued, the flip done gets signalled immediately. Our DSPSURFLIVE check catches this to prevent premature flip completion, but it also means that we don't get a flip done interrupt when the plane actually gets enabled, and so the page flip is never completed. Work around this by re-introducing blocking vblank waits on BDW whenever we enable the primary plane. I removed some of the vblank waits here: commit 6304cd91e7f05f8802ea6f91287cac09741d9c46 Author: Ville Syrjälä Date: Fri Apr 25 13:30:12 2014 +0300 drm/i915: Drop the excessive vblank waits from modeset codepaths To avoid these blocking vblank waits we should start using the vblank interrupt instead of the flip done interrupt to complete page flips. But that's material for another patch. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79354 Tested-by: Guo Jinxian Signed-off-by: Ville Syrjälä Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 9 +++++++++ drivers/gpu/drm/i915/intel_sprite.c | 8 ++++++++ 2 files changed, 17 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5f285fba4e41..33725ed9215a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2087,6 +2087,7 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv, static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv, enum plane plane, enum pipe pipe) { + struct drm_device *dev = dev_priv->dev; struct intel_crtc *intel_crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); int reg; @@ -2106,6 +2107,14 @@ static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv, I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); intel_flush_primary_plane(dev_priv, plane); + + /* + * BDW signals flip done immediately if the plane + * is disabled, even if the plane enable is already + * armed to occur at the next vblank :( + */ + if (IS_BROADWELL(dev)) + intel_wait_for_vblank(dev, intel_crtc->pipe); } /** diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 1b66ddcdfb33..9a17b4e92ef4 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -690,6 +690,14 @@ intel_post_enable_primary(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + /* + * BDW signals flip done immediately if the plane + * is disabled, even if the plane enable is already + * armed to occur at the next vblank :( + */ + if (IS_BROADWELL(dev)) + intel_wait_for_vblank(dev, intel_crtc->pipe); + /* * FIXME IPS should be fine as long as one plane is * enabled, but in practice it seems to have problems -- cgit v1.2.2 From 84b4e042c4707bd1bf05094a51111403d680dc39 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 25 Jun 2014 08:24:29 -0700 Subject: drm/i915: only apply crt_present check on VLV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently we can't trust this field on other platforms and need to find some other way. This fixes a regression introduced in commit 27da3bdfcf7f5233cdfe4563f53edf1ecab7cea0 Author: Jesse Barnes Date: Fri Apr 4 16:12:07 2014 -0700 drm/i915: use VBT to determine whether to enumerate the VGA port Signed-off-by: Jesse Barnes Reviewed-by: Ville Syrjälä Tested-by: Alan Stern Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 33725ed9215a..556c916dbf9d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11097,6 +11097,22 @@ const char *intel_output_name(int output) return names[output]; } +static bool intel_crt_present(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (IS_ULT(dev)) + return false; + + if (IS_CHERRYVIEW(dev)) + return false; + + if (IS_VALLEYVIEW(dev) && !dev_priv->vbt.int_crt_support) + return false; + + return true; +} + static void intel_setup_outputs(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -11105,7 +11121,7 @@ static void intel_setup_outputs(struct drm_device *dev) intel_lvds_init(dev); - if (!IS_ULT(dev) && !IS_CHERRYVIEW(dev) && dev_priv->vbt.int_crt_support) + if (intel_crt_present(dev)) intel_crt_init(dev); if (HAS_DDI(dev)) { -- cgit v1.2.2 From 5549d25f642a7e6cfb8744d0031a9da404f696d6 Mon Sep 17 00:00:00 2001 From: Deepak S Date: Sat, 28 Jun 2014 11:26:11 +0530 Subject: drm/i915: Drop early VLV WA to fix Voltage not getting dropped to Vmin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop WA to fix Voltage not getting dropped to Vmin when Gfx is power gated for latest VLV revision. Workaround fixed in Latest VLV revision. Forcing Gfx clk up not needed, and Requesting the min freq should bring bring the voltage Vnn. v2: Drop WA for Latest VLV revision (Ville) Signed-off-by: Deepak S Reviewed-by: Ville Syrjälä [Jani: modified code comment, reformatted the commit message a bit.] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_pm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9ad0c6afc487..c8bb7616e077 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3209,6 +3209,14 @@ void gen6_set_rps(struct drm_device *dev, u8 val) */ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) { + struct drm_device *dev = dev_priv->dev; + + /* Latest VLV doesn't need to force the gfx clock */ + if (dev->pdev->revision >= 0xd) { + valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); + return; + } + /* * When we are idle. Drop to min voltage state. */ -- cgit v1.2.2 From c149dcb5c60bfea8871f16dfcc0690255eeb825f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 4 Jul 2014 10:00:37 +0800 Subject: drm/i915: provide interface for audio driver to query cdclk For Haswell and Broadwell, if the display power well has been disabled, the display audio controller divider values EM4 M VALUE and EM5 N VALUE will have been lost. The CDCLK frequency is required for reprogramming them to generate 24MHz HD-A link BCLK. So provide a private interface for the audio driver to query CDCLK. This is a stopgap solution until a more generic interface between audio and display drivers has been implemented. Signed-off-by: Jani Nikula Reviewed-by: Damien Lespiau Signed-off-by: Mengdong Lin Cc: Signed-off-by: Takashi Iwai --- drivers/gpu/drm/i915/intel_pm.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6463f0201cf2..409d62676854 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6053,6 +6053,27 @@ int i915_release_power_well(void) } EXPORT_SYMBOL_GPL(i915_release_power_well); +/* + * Private interface for the audio driver to get CDCLK in kHz. + * + * Caller must request power well using i915_request_power_well() prior to + * making the call. + */ +int i915_get_cdclk_freq(void) +{ + struct drm_i915_private *dev_priv; + + if (!hsw_pwr) + return -ENODEV; + + dev_priv = container_of(hsw_pwr, struct drm_i915_private, + power_domains); + + return intel_ddi_get_cdclk_freq(dev_priv); +} +EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); + + #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1) #define HSW_ALWAYS_ON_POWER_DOMAINS ( \ -- cgit v1.2.2 From 0b9f7d93ca6109048a4eb06332b666b6e29df4fe Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Mon, 7 Jul 2014 15:43:51 +0800 Subject: ACPI / i915: ignore firmware requests for backlight change Some Thinkpad laptops' firmware will initiate a backlight level change request through operation region on the events of AC plug/unplug, but since we are not using firmware's interface to do the backlight setting on these affected laptops, we do not want the firmware to use some arbitrary value from its ASL variable to set the backlight level on AC plug/unplug either. Link: https://bugzilla.kernel.org/show_bug.cgi?id=76491 Link: https://bugzilla.kernel.org/show_bug.cgi?id=77091 Reported-and-tested-by: Igor Gnatenko Reported-and-tested-by: Anton Gubarkov Signed-off-by: Aaron Lu Acked-by: Jani Nikula Signed-off-by: Rafael J. Wysocki --- drivers/gpu/drm/i915/intel_opregion.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 2e2c71fcc9ed..4f6b53998d79 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -403,6 +403,15 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); + /* + * If the acpi_video interface is not supposed to be used, don't + * bother processing backlight level change requests from firmware. + */ + if (!acpi_video_verify_backlight_support()) { + DRM_DEBUG_KMS("opregion backlight request ignored\n"); + return 0; + } + if (!(bclp & ASLE_BCLP_VALID)) return ASLC_BACKLIGHT_FAILED; -- cgit v1.2.2 From 9c72cc6f00d24711ef585772396dd1ae180881a6 Mon Sep 17 00:00:00 2001 From: Scot Doyle Date: Thu, 3 Jul 2014 23:27:50 +0000 Subject: drm/i915: quirk asserts controllable backlight presence, overriding VBT commit c675949ec58ca50d5a3ae3c757892f1560f6e896 Author: Jani Nikula Date: Wed Apr 9 11:31:37 2014 +0300 drm/i915: do not setup backlight if not available according to VBT caused a regression on machines with a misconfigured VBT. Add a quirk to assert the presence of a controllable backlight. Use it to ignore the VBT backlight presence check during backlight setup. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79813 Tested-by: James Duley Tested-by: Michael Mullin Reviewed-by: Jani Nikula Signed-off-by: Scot Doyle Signed-off-by: Jani Nikula Cc: stable@vger.kernel.org # 3.15 only [danvet: Add cc: stable because the regressing commit is in 3.15.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 8 ++++++++ drivers/gpu/drm/i915/intel_panel.c | 8 ++++++-- 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a47fbf60b781..374f964323ad 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -656,6 +656,7 @@ enum intel_sbi_destination { #define QUIRK_PIPEA_FORCE (1<<0) #define QUIRK_LVDS_SSC_DISABLE (1<<1) #define QUIRK_INVERT_BRIGHTNESS (1<<2) +#define QUIRK_BACKLIGHT_PRESENT (1<<3) struct intel_fbdev; struct intel_fbc_work; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 556c916dbf9d..949c765037ed 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11591,6 +11591,14 @@ static void quirk_invert_brightness(struct drm_device *dev) DRM_INFO("applying inverted panel brightness quirk\n"); } +/* 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; + dev_priv->quirks |= QUIRK_BACKLIGHT_PRESENT; + DRM_INFO("applying backlight present quirk\n"); +} + struct intel_quirk { int device; int subsystem_vendor; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 38a98570d10c..628cd8938274 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1118,8 +1118,12 @@ int intel_panel_setup_backlight(struct drm_connector *connector) int ret; if (!dev_priv->vbt.backlight.present) { - DRM_DEBUG_KMS("native backlight control not available per VBT\n"); - return 0; + if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) { + DRM_DEBUG_KMS("no backlight present per VBT, but present per quirk\n"); + } else { + DRM_DEBUG_KMS("no backlight present per VBT\n"); + return 0; + } } /* set level and max in panel struct */ -- cgit v1.2.2 From 2e93a1aa9ca455aa3ad0294bcd6d66f38bf8b758 Mon Sep 17 00:00:00 2001 From: Scot Doyle Date: Thu, 3 Jul 2014 23:27:51 +0000 Subject: drm/i915: Acer C720 and C720P have controllable backlights The Acer C720 and C720P Chromebooks (with Celeron 2955U CPU) have a controllable backlight although their VBT reports otherwise. Apply quirk to ignore the backlight presence check during backlight setup. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79813 Tested-by: James Duley Tested-by: Michael Mullin Signed-off-by: Scot Doyle CC: Jani Nikula Signed-off-by: Jani Nikula Cc: stable@vger.kernel.org # 3.15 only [danvet: Add cc: stable because the regressing commit is in 3.15.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 949c765037ed..2ee81656f80a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11667,6 +11667,9 @@ static struct intel_quirk intel_quirks[] = { /* Acer Aspire 5336 */ { 0x2a42, 0x1025, 0x048a, quirk_invert_brightness }, + + /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ + { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, }; static void intel_init_quirks(struct drm_device *dev) -- cgit v1.2.2 From d4967d8c6d4f52623f2be8eaff0b445dc5863c92 Mon Sep 17 00:00:00 2001 From: Scot Doyle Date: Thu, 3 Jul 2014 23:27:52 +0000 Subject: drm/i915: Toshiba CB35 has a controllable backlight The Toshiba CB35 Chromebook (with Celeron 2955U CPU) has a controllable backlight although its VBT reports otherwise. Apply quirk to ignore the backlight presence check during backlight setup. Patch tested by author on Toshiba CB35. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79813 Signed-off-by: Scot Doyle CC: Jani Nikula Signed-off-by: Jani Nikula Cc: stable@vger.kernel.org # 3.15 only [danvet: Add cc: stable because the regressing commit is in 3.15.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2ee81656f80a..e27e7804c0b9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11670,6 +11670,9 @@ static struct intel_quirk intel_quirks[] = { /* Acer C720 and C720P Chromebooks (Celeron 2955U) have backlights */ { 0x0a06, 0x1025, 0x0a11, quirk_backlight_present }, + + /* Toshiba CB35 Chromebook (Celeron 2955U) */ + { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, }; static void intel_init_quirks(struct drm_device *dev) -- cgit v1.2.2 From a799a9780eb5c874d9d7ca0bbee66401ca98c013 Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Thu, 3 Jul 2014 16:35:40 +0530 Subject: drm/i915/vlv: DPI FIFO empty check is not needed While sending DPI SHUTDOWN command, we cannot wait for FIFO empty as pipes are not disabled at that time. In case of MIPI we disable port first and send SHUTDOWN command while pipe is still running and FIFOs will not be empty, causing spurious error log Signed-off-by: Shobhit Kumar Tested-by: Chris Wilson Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi_cmd.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c index 3eeb21b9fddf..933c86305237 100644 --- a/drivers/gpu/drm/i915/intel_dsi_cmd.c +++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c @@ -404,12 +404,6 @@ int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs) else cmd |= DPI_LP_MODE; - /* DPI virtual channel?! */ - - mask = DPI_FIFO_EMPTY; - if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 50)) - DRM_ERROR("Timeout waiting for DPI FIFO empty.\n"); - /* clear bit */ I915_WRITE(MIPI_INTR_STAT(pipe), SPL_PKT_SENT_INTERRUPT); -- cgit v1.2.2 From aceb365ca9a51fb604313c08ed3061d6cc643237 Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Thu, 3 Jul 2014 16:35:41 +0530 Subject: drm/i915/vlv: Update the DSI ULPS entry/exit sequence We should keep DEVICE_READY bit set in the ULPS enter sequence. In exit sequence also we should set DEVICE_READY, but thats causing blankout for me. Also exit sequence is simplified as per hw team recommendation. This should fix - [drm:intel_dsi_clear_device_ready] *ERROR* DSI LP not going Low Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80818 Signed-off-by: Shobhit Kumar Tested-by: Chris Wilson Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dsi.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 02f99d768d49..3fd082933c87 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -117,17 +117,18 @@ static void intel_dsi_device_ready(struct intel_encoder *encoder) /* bandgap reset is needed after everytime we do power gate */ band_gap_reset(dev_priv); + I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); + usleep_range(2500, 3000); + val = I915_READ(MIPI_PORT_CTRL(pipe)); I915_WRITE(MIPI_PORT_CTRL(pipe), val | LP_OUTPUT_HOLD); usleep_range(1000, 1500); - I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT); - usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); - usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); - usleep_range(2000, 2500); + + I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT); + usleep_range(2500, 3000); + I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY); - usleep_range(2000, 2500); + usleep_range(2500, 3000); } static void intel_dsi_enable(struct intel_encoder *encoder) @@ -271,23 +272,23 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) DRM_DEBUG_KMS("\n"); - I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); + I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER); usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_EXIT); + I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_EXIT); usleep_range(2000, 2500); - I915_WRITE(MIPI_DEVICE_READY(pipe), ULPS_STATE_ENTER); + I915_WRITE(MIPI_DEVICE_READY(pipe), DEVICE_READY | ULPS_STATE_ENTER); usleep_range(2000, 2500); - val = I915_READ(MIPI_PORT_CTRL(pipe)); - I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD); - usleep_range(1000, 1500); - if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT) == 0x00000), 30)) DRM_ERROR("DSI LP not going Low\n"); + val = I915_READ(MIPI_PORT_CTRL(pipe)); + I915_WRITE(MIPI_PORT_CTRL(pipe), val & ~LP_OUTPUT_HOLD); + usleep_range(1000, 1500); + I915_WRITE(MIPI_DEVICE_READY(pipe), 0x00); usleep_range(2000, 2500); -- cgit v1.2.2 From f1e1c2129b79cfdaf07bca37c5a10569fe021abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 5 Jun 2014 20:02:59 +0300 Subject: drm/i915: Don't clobber the GTT when it's within stolen memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On most gen2-4 platforms the GTT can be (or maybe always is?) inside the stolen memory region. If that's the case, reduce the size of the stolen memory appropriately to make make sure we don't clobber the GTT. v2: Deal with gen4 36 bit physical address Signed-off-by: Ville Syrjälä Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80151 Acked-by: Chris Wilson Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_stolen.c | 44 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 3 +++ 2 files changed, 47 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 62ef55ba061c..7465ab0fd396 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -74,6 +74,50 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) if (base == 0) return 0; + /* make sure we don't clobber the GTT if it's within stolen memory */ + if (INTEL_INFO(dev)->gen <= 4 && !IS_G33(dev) && !IS_G4X(dev)) { + struct { + u32 start, end; + } stolen[2] = { + { .start = base, .end = base + dev_priv->gtt.stolen_size, }, + { .start = base, .end = base + dev_priv->gtt.stolen_size, }, + }; + u64 gtt_start, gtt_end; + + gtt_start = I915_READ(PGTBL_CTL); + if (IS_GEN4(dev)) + gtt_start = (gtt_start & PGTBL_ADDRESS_LO_MASK) | + (gtt_start & PGTBL_ADDRESS_HI_MASK) << 28; + else + gtt_start &= PGTBL_ADDRESS_LO_MASK; + gtt_end = gtt_start + gtt_total_entries(dev_priv->gtt) * 4; + + if (gtt_start >= stolen[0].start && gtt_start < stolen[0].end) + stolen[0].end = gtt_start; + if (gtt_end > stolen[1].start && gtt_end <= stolen[1].end) + stolen[1].start = gtt_end; + + /* pick the larger of the two chunks */ + if (stolen[0].end - stolen[0].start > + stolen[1].end - stolen[1].start) { + base = stolen[0].start; + dev_priv->gtt.stolen_size = stolen[0].end - stolen[0].start; + } else { + base = stolen[1].start; + dev_priv->gtt.stolen_size = stolen[1].end - stolen[1].start; + } + + if (stolen[0].start != stolen[1].start || + stolen[0].end != stolen[1].end) { + DRM_DEBUG_KMS("GTT within stolen memory at 0x%llx-0x%llx\n", + (unsigned long long) gtt_start, + (unsigned long long) gtt_end - 1); + DRM_DEBUG_KMS("Stolen memory adjusted to 0x%x-0x%x\n", + base, base + (u32) dev_priv->gtt.stolen_size - 1); + } + } + + /* Verify that nothing else uses this physical address. Stolen * memory should be reserved by the BIOS and hidden from the * kernel. So if the region is already marked as busy, something diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e691b30b2817..a5bab61bfc00 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -942,6 +942,9 @@ enum punit_power_well { /* * Instruction and interrupt control regs */ +#define PGTBL_CTL 0x02020 +#define PGTBL_ADDRESS_LO_MASK 0xfffff000 /* bits [31:12] */ +#define PGTBL_ADDRESS_HI_MASK 0x000000f0 /* bits [35:32] (gen4) */ #define PGTBL_ER 0x02024 #define RENDER_RING_BASE 0x02000 #define BSD_RING_BASE 0x04000 -- cgit v1.2.2 From 1bb9e632a0aeee1121e652ee4dc80e5e6f14bcd2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 8 Jul 2014 10:02:43 +0200 Subject: drm/i915: Only unbind vgacon, not other console drivers The console subsystem only provides a function to switch to a given console, but we want to actually only switach away from vgacon. Unconditionally switching to the dummy console resulted in switching away from fbcon in multi-gpu setups when other gpu drivers are loaded before i915. Then either the reinitialization of fbcon when i915 registers its fbdev emulation or the teardown of the fbcon driver killed the machine. So only switch to the dummy console when it's required. Kudos to Chris for the original idea, I've only refined it a bit to still unregister vgacon even when it's currently unused. This regression has been introduced in commit a4de05268e674e8ed31df6348269e22d6c6a1803 Author: Daniel Vetter Date: Thu Jun 5 16:20:46 2014 +0200 drm/i915: Kick out vga console Reported-and-tested-by: Ed Tomlinson Cc: Chris Wilson Cc: David Herrmann Reviewed-by: Chris Wilson Reviewed-by: David Herrmann Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6c656392d67d..d44344140627 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1464,12 +1464,13 @@ static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) #else static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv) { - int ret; + int ret = 0; DRM_INFO("Replacing VGA console driver\n"); console_lock(); - ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1); + 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); -- cgit v1.2.2 From 01527b3127997ef6370d5ad4fa25d96847fbf12a Mon Sep 17 00:00:00 2001 From: Clint Taylor Date: Mon, 7 Jul 2014 13:01:46 -0700 Subject: drm/i915/vlv: T12 eDP panel timing enforcement during reboot The panel power sequencer on vlv doesn't appear to accept changes to its T12 power down duration during warm reboots. This change forces a delay for warm reboots to the T12 panel timing as defined in the VBT table for the connected panel. Ver2: removed redundant pr_crit(), commented magic value for pp_div_reg Ver3: moved SYS_RESTART check earlier, new name for pp_div. Ver4: Minor issue changes Ver5: Move registration of reboot notifier to edp_connector_init, Added warning comment to handler about lack of PM notification. Signed-off-by: Clint Taylor Reviewed-by: Paulo Zanoni Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 42 ++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 2 ++ 2 files changed, 44 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 52fda950fd2a..075170d1844f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -336,6 +338,37 @@ static u32 _pp_stat_reg(struct intel_dp *intel_dp) return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp)); } +/* Reboot notifier handler to shutdown panel power to guarantee T12 timing + This function only applicable when panel PM state is not to be tracked */ +static int edp_notify_handler(struct notifier_block *this, unsigned long code, + void *unused) +{ + 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; + u32 pp_div; + u32 pp_ctrl_reg, pp_div_reg; + enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); + + if (!is_edp(intel_dp) || code != SYS_RESTART) + return 0; + + if (IS_VALLEYVIEW(dev)) { + pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe); + pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe); + pp_div = I915_READ(pp_div_reg); + pp_div &= PP_REFERENCE_DIVIDER_MASK; + + /* 0x1F write to PP_DIV_REG sets max cycle delay */ + I915_WRITE(pp_div_reg, pp_div | 0x1F); + I915_WRITE(pp_ctrl_reg, PANEL_UNLOCK_REGS | PANEL_POWER_OFF); + msleep(intel_dp->panel_power_cycle_delay); + } + + return 0; +} + static bool edp_have_panel_power(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); @@ -3707,6 +3740,10 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); edp_panel_vdd_off_sync(intel_dp); drm_modeset_unlock(&dev->mode_config.connection_mutex); + if (intel_dp->edp_notifier.notifier_call) { + unregister_reboot_notifier(&intel_dp->edp_notifier); + intel_dp->edp_notifier.notifier_call = NULL; + } } kfree(intel_dig_port); } @@ -4184,6 +4221,11 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } mutex_unlock(&dev->mode_config.mutex); + if (IS_VALLEYVIEW(dev)) { + intel_dp->edp_notifier.notifier_call = edp_notify_handler; + register_reboot_notifier(&intel_dp->edp_notifier); + } + intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); intel_panel_setup_backlight(connector); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index eaa27ee9e367..f67340ed2c12 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -538,6 +538,8 @@ struct intel_dp { unsigned long last_power_on; unsigned long last_backlight_off; bool psr_setup_done; + struct notifier_block edp_notifier; + bool use_tps3; struct intel_connector *attached_connector; -- cgit v1.2.2 From 6b89cddee051945a83cc67436ad1680ba7d9f766 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 9 Jul 2014 22:35:53 +0200 Subject: Revert "drm/i915: Don't set the 8to6 dither flag when not scaling" This reverts commit 773875bfb6737982903c42d1ee88cf60af80089c. It is very much needed and the lack of dithering has been reported by a large list of people with various gen2/3 hardware. Also, the original patch was complete non-sense since the WARNING backtraces in the references bugzilla are about gmch_pfit.lvds_border_bits mismatch, not at all about the dither bit. That one seems to work. Cc: Jiri Kosina Cc: Pavel Machek Cc: Hans de Bruin Cc: stable@vger.kernel.org Acked-by: Pavel Machek Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lvds.c | 7 +++++++ drivers/gpu/drm/i915/intel_panel.c | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 23126023aeba..5e5a72fca5fb 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -111,6 +111,13 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, pipe_config->adjusted_mode.flags |= flags; + /* gen2/3 store dither state in pfit control, needs to match */ + if (INTEL_INFO(dev)->gen < 4) { + tmp = I915_READ(PFIT_CONTROL); + + pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE; + } + dotclock = pipe_config->port_clock; if (HAS_PCH_SPLIT(dev_priv->dev)) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 628cd8938274..12b02fe1d0ae 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -361,16 +361,16 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | PFIT_FILTER_FUZZY); - /* Make sure pre-965 set dither correctly for 18bpp panels. */ - if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - out: if ((pfit_control & PFIT_ENABLE) == 0) { pfit_control = 0; pfit_pgm_ratios = 0; } + /* Make sure pre-965 set dither correctly for 18bpp panels. */ + if (INTEL_INFO(dev)->gen < 4 && pipe_config->pipe_bpp == 18) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + pipe_config->gmch_pfit.control = pfit_control; pipe_config->gmch_pfit.pgm_ratios = pfit_pgm_ratios; pipe_config->gmch_pfit.lvds_border_bits = border; -- cgit v1.2.2 From 724cb06fa9b1e1ffd98188275543fdb3b8eaca4f Mon Sep 17 00:00:00 2001 From: Scot Doyle Date: Fri, 11 Jul 2014 22:16:30 +0000 Subject: drm/i915: Ignore VBT backlight presence check on HP Chromebook 14 commit c675949ec58ca50d5a3ae3c757892f1560f6e896 drm/i915: do not setup backlight if not available according to VBT caused a regression on the HP Chromebook 14 (with Celeron 2955U CPU), which has a misconfigured VBT. Apply quirk to ignore the VBT backlight presence check during backlight setup. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79813 Signed-off-by: Scot Doyle Tested-by: Stefan Nagy Cc: Jani Nikula Cc: Daniel Vetter Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e27e7804c0b9..82e7d57f0a8a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11673,6 +11673,9 @@ static struct intel_quirk intel_quirks[] = { /* Toshiba CB35 Chromebook (Celeron 2955U) */ { 0x0a06, 0x1179, 0x0a88, quirk_backlight_present }, + + /* HP Chromebook 14 (Celeron 2955U) */ + { 0x0a06, 0x103c, 0x21ed, quirk_backlight_present }, }; static void intel_init_quirks(struct drm_device *dev) -- cgit v1.2.2 From 9c8958bc24e241de2c0d4740e6dea861fe47daa5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 14 Jul 2014 19:35:31 +0200 Subject: drm/i915: Track the primary plane correctly when reassigning planes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 98ec77397a5c68ce753dc283aaa6f4742328bcdd Author: Ville Syrjälä Date: Wed Apr 30 17:43:01 2014 +0300 drm/i915: Make primary_enabled match the actual hardware state introduced more accurate tracking of the primary plane and some checks. It missed the plane->pipe reassignement code for gen2/3 though, which the checks caught and resulted in WARNING backtraces. Since we only use this path if the plane is on and on the wrong pipe we can just always set the tracking bit to "enabled". Reported-and-tested-by: Paul Bolle Cc: Paul Bolle Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 82e7d57f0a8a..f0be855ddf45 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11914,6 +11914,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) * ... */ plane = crtc->plane; crtc->plane = !plane; + crtc->primary_enabled = true; dev_priv->display.crtc_disable(&crtc->base); crtc->plane = plane; -- cgit v1.2.2 From c6930992948adf0f8fc1f6ff1da51c5002a2cf95 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 14 Jul 2014 11:04:39 +1000 Subject: Revert "drm/i915: reverse dp link param selection, prefer fast over wide again" This reverts commit 38aecea0ccbb909d635619cba22f1891e589b434. This breaks Haswell Thinkpad + Lenovo dock in SST mode with a HDMI monitor attached. Before this we can 1920x1200 mode, after this we only ever get 1024x768, and a lot of deferring. This didn't revert clean, but this should be fine. bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1117008 Cc: stable@vger.kernel.org # v3.15 Signed-off-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 075170d1844f..8a1a4fbc06ac 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -906,8 +906,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, bpp); - for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) { - for (clock = min_clock; clock <= max_clock; clock++) { + for (clock = min_clock; clock <= max_clock; clock++) { + for (lane_count = min_lane_count; lane_count <= max_lane_count; lane_count <<= 1) { link_clock = drm_dp_bw_code_to_link_rate(bws[clock]); link_avail = intel_dp_max_data_rate(link_clock, lane_count); -- cgit v1.2.2