Commit 7c463586 authored by Keith Packard's avatar Keith Packard Committed by Dave Airlie

drm/i915: Manage PIPESTAT to control vblank interrupts instead of IMR.

The pipestat fields affect reporting of all vblank-related interrupts, so we
have to reset them during the irq_handler, and while enabling vblank
interrupts.  Otherwise, if a pipe status field had been set to non-zero
before enabling reporting, we would never see an interrupt again.

This patch adds i915_enable_pipestat and i915_disable_pipestat to abstract
out the steps needed to change the reported interrupts.
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent ed313489
...@@ -132,6 +132,7 @@ typedef struct drm_i915_private { ...@@ -132,6 +132,7 @@ typedef struct drm_i915_private {
int user_irq_refcount; int user_irq_refcount;
/** Cached value of IMR to avoid reads in updating the bitfield */ /** Cached value of IMR to avoid reads in updating the bitfield */
u32 irq_mask_reg; u32 irq_mask_reg;
u32 pipestat[2];
int tex_lru_log_granularity; int tex_lru_log_granularity;
int allow_batchbuffer; int allow_batchbuffer;
...@@ -446,6 +447,13 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data, ...@@ -446,6 +447,13 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
void
i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
void
i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
/* i915_mem.c */ /* i915_mem.c */
extern int i915_mem_alloc(struct drm_device *dev, void *data, extern int i915_mem_alloc(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
......
This diff is collapsed.
...@@ -235,17 +235,15 @@ void opregion_enable_asle(struct drm_device *dev) ...@@ -235,17 +235,15 @@ void opregion_enable_asle(struct drm_device *dev)
struct opregion_asle *asle = dev_priv->opregion.asle; struct opregion_asle *asle = dev_priv->opregion.asle;
if (asle) { if (asle) {
u32 pipeb_stats = I915_READ(PIPEBSTAT);
if (IS_MOBILE(dev)) { if (IS_MOBILE(dev)) {
/* Many devices trigger events with a write to the unsigned long irqflags;
legacy backlight controller, so we need to ensure
that it's able to generate interrupts */ spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
I915_WRITE(PIPEBSTAT, pipeb_stats |= i915_enable_pipestat(dev_priv, 1,
I915_LEGACY_BLC_EVENT_ENABLE); I915_LEGACY_BLC_EVENT_ENABLE);
i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT | spin_unlock_irqrestore(&dev_priv->user_irq_lock,
I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); irqflags);
} else }
i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT);
asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
ASLE_PFMB_EN; ASLE_PFMB_EN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment