* [PATCH 1/7] drm/i915: add panel reset workaround
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
@ 2010-08-18 19:00 ` Jesse Barnes
2010-08-18 19:00 ` [PATCH 2/7] drm/i915: eDP mode set sequence corrections Jesse Barnes
` (8 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 19:00 UTC (permalink / raw)
To: intel-gfx
Ironlake requires that we clear the reset panel bit during power
sequences and restore it afterwards. Uncondtionally add code to do that
since it should be harmless on SNB+.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_dp.c | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5dde80f..048e6a0 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -728,6 +728,12 @@ static void ironlake_edp_panel_on (struct drm_device *dev)
return;
pp = I915_READ(PCH_PP_CONTROL);
+
+ /* ILK workaround: disable reset around power sequence */
+ pp &= ~PANEL_POWER_RESET;
+ I915_WRITE(PCH_PP_CONTROL, pp);
+ POSTING_READ(PCH_PP_CONTROL);
+
pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON;
I915_WRITE(PCH_PP_CONTROL, pp);
do {
@@ -738,7 +744,9 @@ static void ironlake_edp_panel_on (struct drm_device *dev)
DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status);
pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD);
+ pp |= PANEL_POWER_RESET; /* restore panel reset bit */
I915_WRITE(PCH_PP_CONTROL, pp);
+ POSTING_READ(PCH_PP_CONTROL);
}
static void ironlake_edp_panel_off (struct drm_device *dev)
@@ -748,6 +756,12 @@ static void ironlake_edp_panel_off (struct drm_device *dev)
u32 pp, pp_status;
pp = I915_READ(PCH_PP_CONTROL);
+
+ /* ILK workaround: disable reset around power sequence */
+ pp &= ~PANEL_POWER_RESET;
+ I915_WRITE(PCH_PP_CONTROL, pp);
+ POSTING_READ(PCH_PP_CONTROL);
+
pp &= ~POWER_TARGET_ON;
I915_WRITE(PCH_PP_CONTROL, pp);
do {
@@ -758,8 +772,9 @@ static void ironlake_edp_panel_off (struct drm_device *dev)
DRM_DEBUG_KMS("panel off wait timed out\n");
/* Make sure VDD is enabled so DP AUX will work */
- pp |= EDP_FORCE_VDD;
+ pp |= EDP_FORCE_VDD | PANEL_POWER_RESET; /* restore panel reset bit */
I915_WRITE(PCH_PP_CONTROL, pp);
+ POSTING_READ(PCH_PP_CONTROL);
}
static void ironlake_edp_backlight_on (struct drm_device *dev)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 2/7] drm/i915: eDP mode set sequence corrections
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
2010-08-18 19:00 ` [PATCH 1/7] drm/i915: add panel reset workaround Jesse Barnes
@ 2010-08-18 19:00 ` Jesse Barnes
2010-08-18 19:00 ` [PATCH 3/7] drm/i915: fix VGA plane disable for Ironlake+ Jesse Barnes
` (7 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 19:00 UTC (permalink / raw)
To: intel-gfx
We should disable the panel first when shutting down an eDP link. And
when turning one on, the panel needs to be enabled before link training
or eDP I/O won't be enabled.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_dp.c | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 048e6a0..cb62c02 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -809,20 +809,21 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
uint32_t dp_reg = I915_READ(dp_priv->output_reg);
if (mode != DRM_MODE_DPMS_ON) {
+ if (IS_eDP(intel_encoder)) {
+ ironlake_edp_backlight_off(dev);
+ ironlake_edp_panel_off(dev);
+ }
if (dp_reg & DP_PORT_EN) {
intel_dp_link_down(intel_encoder, dp_priv->DP);
- if (IS_eDP(intel_encoder)) {
- ironlake_edp_backlight_off(dev);
- ironlake_edp_panel_off(dev);
- }
}
} else {
if (!(dp_reg & DP_PORT_EN)) {
- intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
- if (IS_eDP(intel_encoder)) {
+ if (IS_eDP(intel_encoder))
ironlake_edp_panel_on(dev);
+ intel_dp_link_train(intel_encoder, dp_priv->DP,
+ dp_priv->link_configuration);
+ if (IS_eDP(intel_encoder))
ironlake_edp_backlight_on(dev);
- }
}
}
dp_priv->dpms_mode = mode;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 3/7] drm/i915: fix VGA plane disable for Ironlake+
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
2010-08-18 19:00 ` [PATCH 1/7] drm/i915: add panel reset workaround Jesse Barnes
2010-08-18 19:00 ` [PATCH 2/7] drm/i915: eDP mode set sequence corrections Jesse Barnes
@ 2010-08-18 19:00 ` Jesse Barnes
2010-08-18 19:00 ` [PATCH 4/7] drm/i915: make sure eDP PLL is enabled at the right time Jesse Barnes
` (6 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 19:00 UTC (permalink / raw)
To: intel-gfx
We need to use I/O port instructions to access VGA registers on
Ironlake+, and it doesn't hurt on other platforms, so switch the VGA
plane disable function over to using them. Move it to init time as well
while we're at it, no need to repeatedly disable the VGA plane with
every mode set and DPMS event.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_display.c | 52 +++++++++++++++------------------
1 files changed, 24 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5e21b31..fe52a3f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1457,29 +1457,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
-/* 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;
- u8 sr1;
- u32 vga_reg;
-
- if (HAS_PCH_SPLIT(dev))
- vga_reg = CPU_VGACNTRL;
- else
- vga_reg = VGACNTRL;
-
- if (I915_READ(vga_reg) & VGA_DISP_DISABLE)
- return;
-
- I915_WRITE8(VGA_SR_INDEX, 1);
- sr1 = I915_READ8(VGA_SR_DATA);
- I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5));
- udelay(100);
-
- I915_WRITE(vga_reg, VGA_DISP_DISABLE);
-}
-
static void ironlake_disable_pll_edp (struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -1994,8 +1971,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_READ(dspbase_reg);
}
- i915_disable_vga(dev);
-
/* disable cpu pipe, disable after all planes disabled */
temp = I915_READ(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) {
@@ -2253,9 +2228,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
dev_priv->display.disable_fbc)
dev_priv->display.disable_fbc(dev);
- /* Disable the VGA plane that we never use */
- i915_disable_vga(dev);
-
/* Disable display plane */
temp = I915_READ(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
@@ -5591,6 +5563,27 @@ 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;
+ u8 sr1;
+ u32 vga_reg;
+
+ if (HAS_PCH_SPLIT(dev))
+ vga_reg = CPU_VGACNTRL;
+ else
+ vga_reg = VGACNTRL;
+
+ outb(1, VGA_SR_INDEX);
+ sr1 = inb(VGA_SR_DATA);
+ outb(sr1 | 1<<5, VGA_SR_DATA);
+ udelay(300);
+
+ I915_WRITE(vga_reg, VGA_DISP_DISABLE);
+ POSTING_READ(vga_reg);
+}
+
void intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5639,6 +5632,9 @@ void intel_modeset_init(struct drm_device *dev)
intel_init_clock_gating(dev);
+ /* Just disable it once at startup */
+ i915_disable_vga(dev);
+
if (IS_IRONLAKE_M(dev)) {
ironlake_enable_drps(dev);
intel_init_emon(dev);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 4/7] drm/i915: make sure eDP PLL is enabled at the right time
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
` (2 preceding siblings ...)
2010-08-18 19:00 ` [PATCH 3/7] drm/i915: fix VGA plane disable for Ironlake+ Jesse Barnes
@ 2010-08-18 19:00 ` Jesse Barnes
2010-08-18 19:00 ` [PATCH 5/7] drm/i915: add MMIO debug output Jesse Barnes
` (5 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 19:00 UTC (permalink / raw)
To: intel-gfx
We need to make sure the eDP PLL is enabled before the pipes or planes,
so do it as part of the DP prepare mode set function.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/intel_display.c | 39 +--------------------
drivers/gpu/drm/i915/intel_dp.c | 63 ++++++++++++++++++++++++++++++++-
2 files changed, 63 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index fe52a3f..6dab095 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1457,31 +1457,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
return 0;
}
-static void ironlake_disable_pll_edp (struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 dpa_ctl;
-
- DRM_DEBUG_KMS("\n");
- dpa_ctl = I915_READ(DP_A);
- dpa_ctl &= ~DP_PLL_ENABLE;
- I915_WRITE(DP_A, dpa_ctl);
-}
-
-static void ironlake_enable_pll_edp (struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- struct drm_i915_private *dev_priv = dev->dev_private;
- u32 dpa_ctl;
-
- dpa_ctl = I915_READ(DP_A);
- dpa_ctl |= DP_PLL_ENABLE;
- I915_WRITE(DP_A, dpa_ctl);
- udelay(200);
-}
-
-
static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock)
{
struct drm_device *dev = crtc->dev;
@@ -1785,11 +1760,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
}
}
- if (HAS_eDP) {
- /* enable eDP PLL */
- ironlake_enable_pll_edp(crtc);
- } else {
-
+ if (!HAS_eDP) {
/* enable PCH FDI RX PLL, wait warmup plus DMI latency */
temp = I915_READ(fdi_rx_reg);
/*
@@ -2099,10 +2070,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE);
I915_READ(pch_dpll_reg);
- if (HAS_eDP) {
- ironlake_disable_pll_edp(crtc);
- }
-
/* Switch from PCDclk to Rawclk */
temp = I915_READ(fdi_rx_reg);
temp &= ~FDI_SEL_PCDCLK;
@@ -3663,9 +3630,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
dpll_reg = pch_dpll_reg;
}
- if (is_edp) {
- ironlake_disable_pll_edp(crtc);
- } else if ((dpll & DPLL_VCO_ENABLE)) {
+ if (!is_edp) {
I915_WRITE(fp_reg, fp);
I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
I915_READ(dpll_reg);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index cb62c02..87b7a49 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -799,6 +799,63 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)
I915_WRITE(PCH_PP_CONTROL, pp);
}
+static void ironlake_edp_pll_on(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 dpa_ctl;
+
+ DRM_DEBUG_KMS("\n");
+ dpa_ctl = I915_READ(DP_A);
+ dpa_ctl &= ~DP_PLL_ENABLE;
+ I915_WRITE(DP_A, dpa_ctl);
+}
+
+static void ironlake_edp_pll_off(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 dpa_ctl;
+
+ dpa_ctl = I915_READ(DP_A);
+ dpa_ctl |= DP_PLL_ENABLE;
+ I915_WRITE(DP_A, dpa_ctl);
+ udelay(200);
+}
+
+static void intel_dp_prepare(struct drm_encoder *encoder)
+{
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t dp_reg = I915_READ(dp_priv->output_reg);
+
+ if (IS_eDP(intel_encoder)) {
+ ironlake_edp_backlight_off(dev);
+ ironlake_edp_panel_on(dev);
+ ironlake_edp_pll_on(encoder);
+ }
+ if (dp_reg & DP_PORT_EN)
+ intel_dp_link_down(intel_encoder, dp_priv->DP);
+}
+
+static void intel_dp_commit(struct drm_encoder *encoder)
+{
+ struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+ struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ struct drm_device *dev = encoder->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ uint32_t dp_reg = I915_READ(dp_priv->output_reg);
+
+ if (!(dp_reg & DP_PORT_EN)) {
+ intel_dp_link_train(intel_encoder, dp_priv->DP,
+ dp_priv->link_configuration);
+ }
+ if (IS_eDP(intel_encoder))
+ ironlake_edp_backlight_on(dev);
+}
+
static void
intel_dp_dpms(struct drm_encoder *encoder, int mode)
{
@@ -816,6 +873,8 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
if (dp_reg & DP_PORT_EN) {
intel_dp_link_down(intel_encoder, dp_priv->DP);
}
+ if (IS_eDP(intel_encoder))
+ ironlake_edp_pll_off(encoder);
} else {
if (!(dp_reg & DP_PORT_EN)) {
if (IS_eDP(intel_encoder))
@@ -1388,9 +1447,9 @@ intel_dp_destroy (struct drm_connector *connector)
static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
.dpms = intel_dp_dpms,
.mode_fixup = intel_dp_mode_fixup,
- .prepare = intel_encoder_prepare,
+ .prepare = intel_dp_prepare,
.mode_set = intel_dp_mode_set,
- .commit = intel_encoder_commit,
+ .commit = intel_dp_commit,
};
static const struct drm_connector_funcs intel_dp_connector_funcs = {
--
1.7.0.4
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 5/7] drm/i915: add MMIO debug output
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
` (3 preceding siblings ...)
2010-08-18 19:00 ` [PATCH 4/7] drm/i915: make sure eDP PLL is enabled at the right time Jesse Barnes
@ 2010-08-18 19:00 ` Jesse Barnes
2010-08-18 19:00 ` [PATCH 6/7] drm/i915: use vga get/put where needed around VGA plane disable Jesse Barnes
` (4 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 19:00 UTC (permalink / raw)
To: intel-gfx
Useful for capturing register read/write traces to send to the hw guys.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_drv.h | 30 ++++++++++++++++++++++++++++--
1 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 2e1744d..8bd566f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -256,6 +256,9 @@ typedef struct drm_i915_private {
int front_offset;
int current_page;
int page_flipping;
+#define I915_DEBUG_READ (1<<0)
+#define I915_DEBUG_WRITE (1<<1)
+ unsigned long debug_flags;
wait_queue_head_t irq_queue;
atomic_t irq_received;
@@ -1065,8 +1068,26 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
LOCK_TEST_WITH_RETURN(dev, file_priv); \
} while (0)
-#define I915_READ(reg) readl(dev_priv->regs + (reg))
-#define I915_WRITE(reg, val) writel(val, dev_priv->regs + (reg))
+static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg)
+{
+ u32 val;
+
+ val = readl(dev_priv->regs + reg);
+ if (dev_priv->debug_flags & I915_DEBUG_READ)
+ printk(KERN_ERR "read 0x%08x from 0x%08x\n", val, reg);
+ return val;
+}
+
+static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg,
+ u32 val)
+{
+ writel(val, dev_priv->regs + reg);
+ if (dev_priv->debug_flags & I915_DEBUG_WRITE)
+ printk(KERN_ERR "wrote 0x%08x to 0x%08x\n", val, reg);
+}
+
+#define I915_READ(reg) i915_read(dev_priv, (reg))
+#define I915_WRITE(reg, val) i915_write(dev_priv, (reg), (val))
#define I915_READ16(reg) readw(dev_priv->regs + (reg))
#define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg))
#define I915_READ8(reg) readb(dev_priv->regs + (reg))
@@ -1076,6 +1097,11 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc);
#define POSTING_READ(reg) (void)I915_READ(reg)
#define POSTING_READ16(reg) (void)I915_READ16(reg)
+#define I915_DEBUG_ENABLE_IO() (dev_priv->debug_flags |= I915_DEBUG_READ | \
+ I915_DEBUG_WRITE)
+#define I915_DEBUG_DISABLE_IO() (dev_priv->debug_flags &= ~(I915_DEBUG_READ | \
+ I915_DEBUG_WRITE))
+
#define I915_VERBOSE 0
#define BEGIN_LP_RING(n) do { \
--
1.7.0.4
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 6/7] drm/i915: use vga get/put where needed around VGA plane disable
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
` (4 preceding siblings ...)
2010-08-18 19:00 ` [PATCH 5/7] drm/i915: add MMIO debug output Jesse Barnes
@ 2010-08-18 19:00 ` Jesse Barnes
2010-08-18 19:00 ` [PATCH 7/7] drm/i915: wait for actual vblank, not just 20ms Jesse Barnes
` (3 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 19:00 UTC (permalink / raw)
To: intel-gfx
---
drivers/gpu/drm/i915/intel_display.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6dab095..928bcc2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -29,6 +29,7 @@
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/vgaarb.h>
#include "drmP.h"
#include "intel_drv.h"
#include "i915_drm.h"
@@ -5540,9 +5541,11 @@ static void i915_disable_vga(struct drm_device *dev)
else
vga_reg = VGACNTRL;
+ vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
outb(1, VGA_SR_INDEX);
sr1 = inb(VGA_SR_DATA);
outb(sr1 | 1<<5, VGA_SR_DATA);
+ vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
udelay(300);
I915_WRITE(vga_reg, VGA_DISP_DISABLE);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 7/7] drm/i915: wait for actual vblank, not just 20ms
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
` (5 preceding siblings ...)
2010-08-18 19:00 ` [PATCH 6/7] drm/i915: use vga get/put where needed around VGA plane disable Jesse Barnes
@ 2010-08-18 19:00 ` Jesse Barnes
2010-08-18 20:48 ` Owain Ainsworth
2010-08-18 19:55 ` More eDP mode setting fixes Adam Jackson
` (2 subsequent siblings)
9 siblings, 1 reply; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 19:00 UTC (permalink / raw)
To: intel-gfx
Waiting for a hard coded 20ms isn't always enough to make sure a vblank
period has actually occurred, so add code to make sure we really have
passed through a vblank period (or that the pipe is off when disabling).
This prevents problems with mode setting and link training, and seems to
fix a bug like https://bugs.freedesktop.org/show_bug.cgi?id=29278, but
on an HP 8440p instead. Hopefully also fixes
https://bugs.freedesktop.org/show_bug.cgi?id=29141.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_reg.h | 1 +
drivers/gpu/drm/i915/intel_crt.c | 2 +-
drivers/gpu/drm/i915/intel_display.c | 75 ++++++++++++++++++++++++++--------
drivers/gpu/drm/i915/intel_dp.c | 3 +-
drivers/gpu/drm/i915/intel_drv.h | 3 +-
drivers/gpu/drm/i915/intel_sdvo.c | 3 +-
drivers/gpu/drm/i915/intel_tv.c | 9 ++--
7 files changed, 71 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index cf41c67..822b21c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2080,6 +2080,7 @@
#define PIPE_DITHER_TYPE_ST01 (1 << 2)
/* Pipe A */
#define PIPEADSL 0x70000
+#define DSL_LINEMASK 0x00000fff
#define PIPEACONF 0x70008
#define PIPEACONF_ENABLE (1<<31)
#define PIPEACONF_DISABLE 0
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index ee0732b..4a2f593 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -331,7 +331,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
/* Wait for next Vblank to substitue
* border color for Color info */
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, pipe);
st00 = I915_READ8(VGA_MSR_WRITE);
status = ((st00 & (1 << 4)) != 0) ?
connector_status_connected :
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 928bcc2..27e60b8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -972,11 +972,57 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
return true;
}
-void
-intel_wait_for_vblank(struct drm_device *dev)
+/**
+ * intel_wait_for_vblank - wait for vblank on a given pipe
+ * @dev: drm device
+ * @pipe: pipe to wait for
+ *
+ * Wait for vblank to occur on a given pipe. Needed for various bits of
+ * mode setting code.
+ */
+void intel_wait_for_vblank(struct drm_device *dev, int pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT);
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+ /* Wait for vblank interrupt bit to set */
+ while (!(I915_READ(pipestat_reg) & PIPE_VBLANK_INTERRUPT_STATUS) &&
+ time_after(timeout, jiffies))
+ mdelay(1);
+
+ if (time_after(jiffies, timeout))
+ DRM_DEBUG_KMS("vblank wait timed out\n");
+}
+
+/**
+ * intel_wait_for_vblank_off - wait for vblank after disabling a pipe
+ * @dev: drm device
+ * @pipe: pipe to wait for
+ *
+ * After disabling a pipe, we can't wait for vblank in the usual way,
+ * spinning on the vblank interrupt status bit, since we won't actually
+ * see an interrupt when the pipe is disabled.
+ *
+ * So this function waits for the display line value to settle (it
+ * usually ends up stopping at the start of the next frame).
+ */
+void intel_wait_for_vblank_off(struct drm_device *dev, int pipe)
{
- /* Wait for 20ms, i.e. one cycle at 50hz. */
- msleep(20);
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+ u32 last_line;
+
+ /* Wait for the display line to settle */
+ do {
+ last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
+ mdelay(5);
+ } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) &&
+ time_after(timeout, jiffies));
+
+ if (time_after(jiffies, timeout))
+ DRM_DEBUG_KMS("vblank wait timed out\n");
}
/* Parameters have changed, update FBC info */
@@ -1053,8 +1099,6 @@ void i8xx_disable_fbc(struct drm_device *dev)
; /* do nothing */
}
- intel_wait_for_vblank(dev);
-
DRM_DEBUG_KMS("disabled FBC\n");
}
@@ -1111,7 +1155,6 @@ void g4x_disable_fbc(struct drm_device *dev)
dpfc_ctl = I915_READ(DPFC_CONTROL);
dpfc_ctl &= ~DPFC_CTL_EN;
I915_WRITE(DPFC_CONTROL, dpfc_ctl);
- intel_wait_for_vblank(dev);
DRM_DEBUG_KMS("disabled FBC\n");
}
@@ -1429,7 +1472,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
if ((IS_I965G(dev) || plane == 0))
intel_update_fbc(crtc, &crtc->mode);
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, pipe);
if (old_fb) {
intel_fb = to_intel_framebuffer(old_fb);
@@ -2205,10 +2248,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_READ(dspbase_reg);
}
- if (!IS_I9XX(dev)) {
- /* Wait for vblank for the disable to take effect */
- intel_wait_for_vblank(dev);
- }
+ /* Wait for vblank for the disable to take effect */
+ intel_wait_for_vblank_off(dev, pipe);
/* Don't disable pipe A or pipe A PLLs if needed */
if (pipeconf_reg == PIPEACONF &&
@@ -2223,7 +2264,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
}
/* Wait for vblank for the disable to take effect. */
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank_off(dev, pipe);
temp = I915_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) != 0) {
@@ -3828,7 +3869,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(pipeconf_reg, pipeconf);
I915_READ(pipeconf_reg);
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, pipe);
if (IS_IRONLAKE(dev)) {
/* enable address swizzle for tiling buffer */
@@ -4170,7 +4211,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
encoder_funcs->commit(encoder);
}
/* let the connector get through one full cycle before testing */
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
return crtc;
}
@@ -4375,7 +4416,7 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule)
dpll &= ~DISPLAY_RATE_SELECT_FPA1;
I915_WRITE(dpll_reg, dpll);
dpll = I915_READ(dpll_reg);
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, pipe);
dpll = I915_READ(dpll_reg);
if (dpll & DISPLAY_RATE_SELECT_FPA1)
DRM_DEBUG_DRIVER("failed to upclock LVDS!\n");
@@ -4419,7 +4460,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
dpll |= DISPLAY_RATE_SELECT_FPA1;
I915_WRITE(dpll_reg, dpll);
dpll = I915_READ(dpll_reg);
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, pipe);
dpll = I915_READ(dpll_reg);
if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 87b7a49..e008587 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1120,12 +1120,13 @@ intel_dp_set_link_train(struct intel_encoder *intel_encoder,
struct drm_device *dev = intel_encoder->enc.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+ struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->enc.crtc);
int ret;
I915_WRITE(dp_priv->output_reg, dp_reg_value);
POSTING_READ(dp_priv->output_reg);
if (first)
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
intel_dp_aux_native_write_1(intel_encoder,
DP_TRAINING_PATTERN_SET,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2f7970b..93340ed 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -193,7 +193,8 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
struct drm_crtc *crtc);
int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern void intel_wait_for_vblank(struct drm_device *dev);
+extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe);
+extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
struct drm_connector *connector,
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 76993ac..353e400 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1275,6 +1275,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+ struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->enc.crtc);
u32 temp;
if (mode != DRM_MODE_DPMS_ON) {
@@ -1297,7 +1298,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
if ((temp & SDVO_ENABLE) == 0)
intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
for (i = 0; i < 2; i++)
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
&input2);
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 6d553c2..6651855 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1156,11 +1156,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
/* Wait for vblank for the disable to take effect */
if (!IS_I9XX(dev))
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
/* Wait for vblank for the disable to take effect. */
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
/* Filter ctl must be set before TV_WIN_SIZE */
I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
@@ -1229,6 +1229,7 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder
struct drm_encoder *encoder = &intel_encoder->enc;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(intel_encoder->enc.crtc);
unsigned long irqflags;
u32 tv_ctl, save_tv_ctl;
u32 tv_dac, save_tv_dac;
@@ -1265,11 +1266,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder
DAC_C_0_7_V);
I915_WRITE(TV_CTL, tv_ctl);
I915_WRITE(TV_DAC, tv_dac);
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
tv_dac = I915_READ(TV_DAC);
I915_WRITE(TV_DAC, save_tv_dac);
I915_WRITE(TV_CTL, save_tv_ctl);
- intel_wait_for_vblank(dev);
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
/*
* A B C
* 0 1 1 Composite
--
1.7.0.4
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 7/7] drm/i915: wait for actual vblank, not just 20ms
2010-08-18 19:00 ` [PATCH 7/7] drm/i915: wait for actual vblank, not just 20ms Jesse Barnes
@ 2010-08-18 20:48 ` Owain Ainsworth
2010-08-18 21:05 ` Jesse Barnes
0 siblings, 1 reply; 14+ messages in thread
From: Owain Ainsworth @ 2010-08-18 20:48 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
On Wed, Aug 18, 2010 at 12:00:36PM -0700, Jesse Barnes wrote:
> Waiting for a hard coded 20ms isn't always enough to make sure a vblank
> period has actually occurred, so add code to make sure we really have
> passed through a vblank period (or that the pipe is off when disabling).
>
> This prevents problems with mode setting and link training, and seems to
> fix a bug like https://bugs.freedesktop.org/show_bug.cgi?id=29278, but
> on an HP 8440p instead. Hopefully also fixes
> https://bugs.freedesktop.org/show_bug.cgi?id=29141.
>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> ---
> drivers/gpu/drm/i915/i915_reg.h | 1 +
> drivers/gpu/drm/i915/intel_crt.c | 2 +-
> drivers/gpu/drm/i915/intel_display.c | 75 ++++++++++++++++++++++++++--------
> drivers/gpu/drm/i915/intel_dp.c | 3 +-
> drivers/gpu/drm/i915/intel_drv.h | 3 +-
> drivers/gpu/drm/i915/intel_sdvo.c | 3 +-
> drivers/gpu/drm/i915/intel_tv.c | 9 ++--
> 7 files changed, 71 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index cf41c67..822b21c 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -2080,6 +2080,7 @@
> #define PIPE_DITHER_TYPE_ST01 (1 << 2)
> /* Pipe A */
> #define PIPEADSL 0x70000
> +#define DSL_LINEMASK 0x00000fff
> #define PIPEACONF 0x70008
> #define PIPEACONF_ENABLE (1<<31)
> #define PIPEACONF_DISABLE 0
> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> index ee0732b..4a2f593 100644
> --- a/drivers/gpu/drm/i915/intel_crt.c
> +++ b/drivers/gpu/drm/i915/intel_crt.c
> @@ -331,7 +331,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
> I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
> /* Wait for next Vblank to substitue
> * border color for Color info */
> - intel_wait_for_vblank(dev);
> + intel_wait_for_vblank(dev, pipe);
> st00 = I915_READ8(VGA_MSR_WRITE);
> status = ((st00 & (1 << 4)) != 0) ?
> connector_status_connected :
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 928bcc2..27e60b8 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -972,11 +972,57 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
> return true;
> }
>
> -void
> -intel_wait_for_vblank(struct drm_device *dev)
> +/**
> + * intel_wait_for_vblank - wait for vblank on a given pipe
> + * @dev: drm device
> + * @pipe: pipe to wait for
> + *
> + * Wait for vblank to occur on a given pipe. Needed for various bits of
> + * mode setting code.
> + */
> +void intel_wait_for_vblank(struct drm_device *dev, int pipe)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT);
> + unsigned long timeout = jiffies + msecs_to_jiffies(100);
> +
> + /* Wait for vblank interrupt bit to set */
> + while (!(I915_READ(pipestat_reg) & PIPE_VBLANK_INTERRUPT_STATUS) &&
> + time_after(timeout, jiffies))
> + mdelay(1);
Why not actually go to sleep and let the interrupt wake you up? let the
machine do something else in the meantime.
-0-
--
You cannot kill time without injuring eternity.
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 7/7] drm/i915: wait for actual vblank, not just 20ms
2010-08-18 20:48 ` Owain Ainsworth
@ 2010-08-18 21:05 ` Jesse Barnes
2010-08-18 21:12 ` Andrew Lutomirski
0 siblings, 1 reply; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 21:05 UTC (permalink / raw)
To: Owain Ainsworth; +Cc: intel-gfx
On Wed, 18 Aug 2010 21:48:50 +0100
Owain Ainsworth <zerooa@googlemail.com> wrote:
> On Wed, Aug 18, 2010 at 12:00:36PM -0700, Jesse Barnes wrote:
> > Waiting for a hard coded 20ms isn't always enough to make sure a vblank
> > period has actually occurred, so add code to make sure we really have
> > passed through a vblank period (or that the pipe is off when disabling).
> >
> > This prevents problems with mode setting and link training, and seems to
> > fix a bug like https://bugs.freedesktop.org/show_bug.cgi?id=29278, but
> > on an HP 8440p instead. Hopefully also fixes
> > https://bugs.freedesktop.org/show_bug.cgi?id=29141.
> >
> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> > ---
> > drivers/gpu/drm/i915/i915_reg.h | 1 +
> > drivers/gpu/drm/i915/intel_crt.c | 2 +-
> > drivers/gpu/drm/i915/intel_display.c | 75 ++++++++++++++++++++++++++--------
> > drivers/gpu/drm/i915/intel_dp.c | 3 +-
> > drivers/gpu/drm/i915/intel_drv.h | 3 +-
> > drivers/gpu/drm/i915/intel_sdvo.c | 3 +-
> > drivers/gpu/drm/i915/intel_tv.c | 9 ++--
> > 7 files changed, 71 insertions(+), 25 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> > index cf41c67..822b21c 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -2080,6 +2080,7 @@
> > #define PIPE_DITHER_TYPE_ST01 (1 << 2)
> > /* Pipe A */
> > #define PIPEADSL 0x70000
> > +#define DSL_LINEMASK 0x00000fff
> > #define PIPEACONF 0x70008
> > #define PIPEACONF_ENABLE (1<<31)
> > #define PIPEACONF_DISABLE 0
> > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> > index ee0732b..4a2f593 100644
> > --- a/drivers/gpu/drm/i915/intel_crt.c
> > +++ b/drivers/gpu/drm/i915/intel_crt.c
> > @@ -331,7 +331,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
> > I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
> > /* Wait for next Vblank to substitue
> > * border color for Color info */
> > - intel_wait_for_vblank(dev);
> > + intel_wait_for_vblank(dev, pipe);
> > st00 = I915_READ8(VGA_MSR_WRITE);
> > status = ((st00 & (1 << 4)) != 0) ?
> > connector_status_connected :
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 928bcc2..27e60b8 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -972,11 +972,57 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
> > return true;
> > }
> >
> > -void
> > -intel_wait_for_vblank(struct drm_device *dev)
> > +/**
> > + * intel_wait_for_vblank - wait for vblank on a given pipe
> > + * @dev: drm device
> > + * @pipe: pipe to wait for
> > + *
> > + * Wait for vblank to occur on a given pipe. Needed for various bits of
> > + * mode setting code.
> > + */
> > +void intel_wait_for_vblank(struct drm_device *dev, int pipe)
> > +{
> > + struct drm_i915_private *dev_priv = dev->dev_private;
> > + int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT);
> > + unsigned long timeout = jiffies + msecs_to_jiffies(100);
> > +
> > + /* Wait for vblank interrupt bit to set */
> > + while (!(I915_READ(pipestat_reg) & PIPE_VBLANK_INTERRUPT_STATUS) &&
> > + time_after(timeout, jiffies))
> > + mdelay(1);
>
> Why not actually go to sleep and let the interrupt wake you up? let the
> machine do something else in the meantime.
Yeah, I thought that might be nice, but I was worried about locking and
the KDB paths...
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 7/7] drm/i915: wait for actual vblank, not just 20ms
2010-08-18 21:05 ` Jesse Barnes
@ 2010-08-18 21:12 ` Andrew Lutomirski
0 siblings, 0 replies; 14+ messages in thread
From: Andrew Lutomirski @ 2010-08-18 21:12 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
On Wed, Aug 18, 2010 at 5:05 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> On Wed, 18 Aug 2010 21:48:50 +0100
> Owain Ainsworth <zerooa@googlemail.com> wrote:
>
>> On Wed, Aug 18, 2010 at 12:00:36PM -0700, Jesse Barnes wrote:
>> > Waiting for a hard coded 20ms isn't always enough to make sure a vblank
>> > period has actually occurred, so add code to make sure we really have
>> > passed through a vblank period (or that the pipe is off when disabling).
>> >
>> > This prevents problems with mode setting and link training, and seems to
>> > fix a bug like https://bugs.freedesktop.org/show_bug.cgi?id=29278, but
>> > on an HP 8440p instead. Hopefully also fixes
>> > https://bugs.freedesktop.org/show_bug.cgi?id=29141.
>> >
>> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
>> > ---
>> > drivers/gpu/drm/i915/i915_reg.h | 1 +
>> > drivers/gpu/drm/i915/intel_crt.c | 2 +-
>> > drivers/gpu/drm/i915/intel_display.c | 75 ++++++++++++++++++++++++++--------
>> > drivers/gpu/drm/i915/intel_dp.c | 3 +-
>> > drivers/gpu/drm/i915/intel_drv.h | 3 +-
>> > drivers/gpu/drm/i915/intel_sdvo.c | 3 +-
>> > drivers/gpu/drm/i915/intel_tv.c | 9 ++--
>> > 7 files changed, 71 insertions(+), 25 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> > index cf41c67..822b21c 100644
>> > --- a/drivers/gpu/drm/i915/i915_reg.h
>> > +++ b/drivers/gpu/drm/i915/i915_reg.h
>> > @@ -2080,6 +2080,7 @@
>> > #define PIPE_DITHER_TYPE_ST01 (1 << 2)
>> > /* Pipe A */
>> > #define PIPEADSL 0x70000
>> > +#define DSL_LINEMASK 0x00000fff
>> > #define PIPEACONF 0x70008
>> > #define PIPEACONF_ENABLE (1<<31)
>> > #define PIPEACONF_DISABLE 0
>> > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
>> > index ee0732b..4a2f593 100644
>> > --- a/drivers/gpu/drm/i915/intel_crt.c
>> > +++ b/drivers/gpu/drm/i915/intel_crt.c
>> > @@ -331,7 +331,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
>> > I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
>> > /* Wait for next Vblank to substitue
>> > * border color for Color info */
>> > - intel_wait_for_vblank(dev);
>> > + intel_wait_for_vblank(dev, pipe);
>> > st00 = I915_READ8(VGA_MSR_WRITE);
>> > status = ((st00 & (1 << 4)) != 0) ?
>> > connector_status_connected :
>> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> > index 928bcc2..27e60b8 100644
>> > --- a/drivers/gpu/drm/i915/intel_display.c
>> > +++ b/drivers/gpu/drm/i915/intel_display.c
>> > @@ -972,11 +972,57 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
>> > return true;
>> > }
>> >
>> > -void
>> > -intel_wait_for_vblank(struct drm_device *dev)
>> > +/**
>> > + * intel_wait_for_vblank - wait for vblank on a given pipe
>> > + * @dev: drm device
>> > + * @pipe: pipe to wait for
>> > + *
>> > + * Wait for vblank to occur on a given pipe. Needed for various bits of
>> > + * mode setting code.
>> > + */
>> > +void intel_wait_for_vblank(struct drm_device *dev, int pipe)
>> > +{
>> > + struct drm_i915_private *dev_priv = dev->dev_private;
>> > + int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT);
>> > + unsigned long timeout = jiffies + msecs_to_jiffies(100);
>> > +
>> > + /* Wait for vblank interrupt bit to set */
>> > + while (!(I915_READ(pipestat_reg) & PIPE_VBLANK_INTERRUPT_STATUS) &&
>> > + time_after(timeout, jiffies))
>> > + mdelay(1);
>>
>> Why not actually go to sleep and let the interrupt wake you up? let the
>> machine do something else in the meantime.
>
> Yeah, I thought that might be nice, but I was worried about locking and
> the KDB paths...
msleep at least? that's a lot of latency on single-processor otherwise.
>
> --
> Jesse Barnes, Intel Open Source Technology Center
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: More eDP mode setting fixes
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
` (6 preceding siblings ...)
2010-08-18 19:00 ` [PATCH 7/7] drm/i915: wait for actual vblank, not just 20ms Jesse Barnes
@ 2010-08-18 19:55 ` Adam Jackson
2010-08-18 20:24 ` Jesse Barnes
2010-08-22 6:24 ` Eric Anholt
9 siblings, 0 replies; 14+ messages in thread
From: Adam Jackson @ 2010-08-18 19:55 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 343 bytes --]
On Wed, 2010-08-18 at 12:00 -0700, Jesse Barnes wrote:
> This set replaces the last one, and includes an additional patch to fix
> our vblank wait code, which is apparently important especially when
> dealing with link training.
I always did hate that msleep.
Reviewed-by: Adam Jackson <ajax@redhat.com>
for the series.
- ajax
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: More eDP mode setting fixes
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
` (7 preceding siblings ...)
2010-08-18 19:55 ` More eDP mode setting fixes Adam Jackson
@ 2010-08-18 20:24 ` Jesse Barnes
2010-08-22 6:24 ` Eric Anholt
9 siblings, 0 replies; 14+ messages in thread
From: Jesse Barnes @ 2010-08-18 20:24 UTC (permalink / raw)
To: eric; +Cc: intel-gfx
On Wed, 18 Aug 2010 12:00:29 -0700
Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> This set replaces the last one, and includes an additional patch to fix
> our vblank wait code, which is apparently important especially when
> dealing with link training.
>
> It also contains a patch to address Adam's comment about the new VGA
> disable code. I was missing a vga get/put pair around my access of
> SR01.
Eric, a pullable git tree with these changes (rebased to
drm-intel-next) is in the drm-intel-next branch of my drm-intel tree at
kernel.org. Testing the new combination now.
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: More eDP mode setting fixes
2010-08-18 19:00 More eDP mode setting fixes Jesse Barnes
` (8 preceding siblings ...)
2010-08-18 20:24 ` Jesse Barnes
@ 2010-08-22 6:24 ` Eric Anholt
9 siblings, 0 replies; 14+ messages in thread
From: Eric Anholt @ 2010-08-22 6:24 UTC (permalink / raw)
To: Jesse Barnes, intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 547 bytes --]
On Wed, 18 Aug 2010 12:00:29 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> This set replaces the last one, and includes an additional patch to fix
> our vblank wait code, which is apparently important especially when
> dealing with link training.
>
> It also contains a patch to address Adam's comment about the new VGA
> disable code. I was missing a vga get/put pair around my access of
> SR01.
I pulled your tree minus the additional debug code. This is quite a
tree I've got queued up already, trying to play it safe.
[-- Attachment #1.2: Type: application/pgp-signature, Size: 197 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 14+ messages in thread