From: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> Fixes regression introduced by: commit bf51d5e2cda5d36d98e4b46ac7fca9461e512c41 Author: Paulo Zanoni <paulo.r.zanoni at intel.com> Date: Wed Jul 3 17:12:13 2013 -0300 drm/i915: switch disable_power_well default value to 1 The bug I'm seeing can be reproduced with: - Boot your Haswell machine - Make sure the power well gets disabled, then enabled. You can check this by seeing the messages print by hsw_set_power_well - Stop your display manager - echo 0 > /sys/class/vtconsole/vtcon1/bind I can easily reproduce this by blacklising snd_hda_intel and booting with eDP+HDMI. If you do this and then look at dmesg, you'll see we're printing infinite "Unclaimed register" messages. This is happening because we're stuck on an infinite loop inside console_unlock(), which is calling many functions from vgacon.c. And the code that's triggering the error messages is from vgacon_set_cursor_size(). For some reason, what fixes the problem is the code that clears VGA_MSR_MEM_EN from VGA_MSR_WRITE. If you add some debug messages, you'll see that we're reading a value of 0 and writing 0 back to it. I really don't know why this fixes the problem, but I am sure that if you remove the code line that writes 0 back the bug won't stop. I suspect this is probably some problem with how the hardware gets reinitialized when we reenable the power well. Also notice that function i915_disable_vga_mem already existed and was removed on commit 6e1b4fdad5157bb9e88777d525704aba24389bee, I just brought it back. Notice that the intel_drv.h declaration was still there too. I know some people will probably request to deeply investigate why exactly vgacon is doing the wrong thing, and ask me to replace the "for (;;)" that exists inside console_unlock() with something else, but my goal here is to just fix the regression. I don't think it's worth spending that much time on vgacon code. And this is our regression anyway. Notice that this is just a partial fix to fd.o #67813. This fixes the case where the power well is already enabled when we unbind, not when it's disabled when we unbind. V2: - Rebase (first version was sent in September). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67813 Signed-off-by: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_display.c | 12 ++++++++++++ drivers/gpu/drm/i915/intel_pm.c | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 45a87d1..bf22bea 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11064,6 +11064,18 @@ void i915_redisable_vga(struct drm_device *dev) } } +void i915_disable_vga_mem(struct drm_device *dev) +{ + if (HAS_PCH_SPLIT(dev)) { + vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); + outb(inb(VGA_MSR_READ) & ~VGA_MSR_MEM_EN, VGA_MSR_WRITE); + vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO | + VGA_RSRC_NORMAL_IO | + VGA_RSRC_NORMAL_MEM); + vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); + } +} + static void intel_modeset_readout_hw_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e6d98fe..7ebe1bd 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5703,6 +5703,8 @@ static void hsw_set_power_well(struct drm_device *dev, if (wait_for((I915_READ(HSW_PWR_WELL_DRIVER) & HSW_PWR_WELL_STATE_ENABLED), 20)) DRM_ERROR("Timeout enabling power well\n"); + + i915_disable_vga_mem(dev); } if (IS_BROADWELL(dev)) { -- 1.8.3.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx