Commit 5380e929 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Dave Airlie

drm: Collect per-crtc vblank stuff to a struct

drm_vblank_init() is too ugly. Make it a bit easier on the eye by
collecting all the per-crtc vblank counters, timestamps etc. to
a structure and just allocate an array of those.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent bf507d90
...@@ -163,13 +163,13 @@ int drm_vblank_info(struct seq_file *m, void *data) ...@@ -163,13 +163,13 @@ int drm_vblank_info(struct seq_file *m, void *data)
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
for (crtc = 0; crtc < dev->num_crtcs; crtc++) { for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
seq_printf(m, "CRTC %d enable: %d\n", seq_printf(m, "CRTC %d enable: %d\n",
crtc, atomic_read(&dev->vblank_refcount[crtc])); crtc, atomic_read(&dev->vblank[crtc].refcount));
seq_printf(m, "CRTC %d counter: %d\n", seq_printf(m, "CRTC %d counter: %d\n",
crtc, drm_vblank_count(dev, crtc)); crtc, drm_vblank_count(dev, crtc));
seq_printf(m, "CRTC %d last wait: %d\n", seq_printf(m, "CRTC %d last wait: %d\n",
crtc, dev->last_vblank_wait[crtc]); crtc, dev->vblank[crtc].last_wait);
seq_printf(m, "CRTC %d in modeset: %d\n", seq_printf(m, "CRTC %d in modeset: %d\n",
crtc, dev->vblank_inmodeset[crtc]); crtc, dev->vblank[crtc].inmodeset);
} }
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
return 0; return 0;
......
This diff is collapsed.
...@@ -271,15 +271,15 @@ void psb_irq_preinstall(struct drm_device *dev) ...@@ -271,15 +271,15 @@ void psb_irq_preinstall(struct drm_device *dev)
if (gma_power_is_on(dev)) if (gma_power_is_on(dev))
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
if (dev->vblank_enabled[0]) if (dev->vblank[0].enabled)
dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
if (dev->vblank_enabled[1]) if (dev->vblank[1].enabled)
dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
/* FIXME: Handle Medfield irq mask /* FIXME: Handle Medfield irq mask
if (dev->vblank_enabled[1]) if (dev->vblank[1].enabled)
dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
if (dev->vblank_enabled[2]) if (dev->vblank[2].enabled)
dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
*/ */
...@@ -305,17 +305,17 @@ int psb_irq_postinstall(struct drm_device *dev) ...@@ -305,17 +305,17 @@ int psb_irq_postinstall(struct drm_device *dev)
PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
if (dev->vblank_enabled[0]) if (dev->vblank[0].enabled)
psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
else else
psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
if (dev->vblank_enabled[1]) if (dev->vblank[1].enabled)
psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
else else
psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
if (dev->vblank_enabled[2]) if (dev->vblank[2].enabled)
psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
else else
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
...@@ -339,13 +339,13 @@ void psb_irq_uninstall(struct drm_device *dev) ...@@ -339,13 +339,13 @@ void psb_irq_uninstall(struct drm_device *dev)
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
if (dev->vblank_enabled[0]) if (dev->vblank[0].enabled)
psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
if (dev->vblank_enabled[1]) if (dev->vblank[1].enabled)
psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
if (dev->vblank_enabled[2]) if (dev->vblank[2].enabled)
psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
...@@ -456,7 +456,7 @@ static int psb_vblank_do_wait(struct drm_device *dev, ...@@ -456,7 +456,7 @@ static int psb_vblank_do_wait(struct drm_device *dev,
{ {
unsigned int cur_vblank; unsigned int cur_vblank;
int ret = 0; int ret = 0;
DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, DRM_WAIT_ON(ret, dev->vblank.queue, 3 * DRM_HZ,
(((cur_vblank = atomic_read(counter)) (((cur_vblank = atomic_read(counter))
- *sequence) <= (1 << 23))); - *sequence) <= (1 << 23)));
*sequence = cur_vblank; *sequence = cur_vblank;
......
...@@ -5340,7 +5340,7 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) ...@@ -5340,7 +5340,7 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable)
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
for_each_pipe(p) for_each_pipe(p)
if (p != PIPE_A) if (p != PIPE_A)
dev->last_vblank[p] = 0; dev->vblank[p].last = 0;
spin_unlock_irqrestore(&dev->vbl_lock, irqflags); spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
} }
} }
......
...@@ -307,9 +307,9 @@ int omap_drm_irq_uninstall(struct drm_device *dev) ...@@ -307,9 +307,9 @@ int omap_drm_irq_uninstall(struct drm_device *dev)
if (dev->num_crtcs) { if (dev->num_crtcs) {
spin_lock_irqsave(&dev->vbl_lock, irqflags); spin_lock_irqsave(&dev->vbl_lock, irqflags);
for (i = 0; i < dev->num_crtcs; i++) { for (i = 0; i < dev->num_crtcs; i++) {
DRM_WAKEUP(&dev->vbl_queue[i]); DRM_WAKEUP(&dev->vblank[i].queue);
dev->vblank_enabled[i] = false; dev->vblank[i].enabled = false;
dev->last_vblank[i] = dev->vblank[i].last =
dev->driver->get_vblank_counter(dev, i); dev->driver->get_vblank_counter(dev, i);
} }
spin_unlock_irqrestore(&dev->vbl_lock, irqflags); spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
......
...@@ -1078,6 +1078,19 @@ struct drm_pending_vblank_event { ...@@ -1078,6 +1078,19 @@ struct drm_pending_vblank_event {
struct drm_event_vblank event; struct drm_event_vblank event;
}; };
struct drm_vblank_crtc {
wait_queue_head_t queue; /**< VBLANK wait queue */
struct timeval time[DRM_VBLANKTIME_RBSIZE]; /**< timestamp of current count */
atomic_t count; /**< number of VBLANK interrupts */
atomic_t refcount; /* number of users of vblank interruptsper crtc */
u32 last; /* protected by dev->vbl_lock, used */
/* for wraparound handling */
u32 last_wait; /* Last vblank seqno waited per CRTC */
unsigned int inmodeset; /* Display driver is setting mode */
bool enabled; /* so we don't call enable more than
once per disable */
};
/** /**
* DRM device structure. This structure represent a complete card that * DRM device structure. This structure represent a complete card that
* may contain multiple heads. * may contain multiple heads.
...@@ -1153,18 +1166,11 @@ struct drm_device { ...@@ -1153,18 +1166,11 @@ struct drm_device {
*/ */
bool vblank_disable_allowed; bool vblank_disable_allowed;
wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ /* array of size num_crtcs */
atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ struct drm_vblank_crtc *vblank;
struct timeval *_vblank_time; /**< timestamp of current vblank_count (drivers must alloc right number of fields) */
spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */
spinlock_t vbl_lock; spinlock_t vbl_lock;
atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
u32 *last_vblank; /* protected by dev->vbl_lock, used */
/* for wraparound handling */
bool *vblank_enabled; /* so we don't call enable more than
once per disable */
unsigned int *vblank_inmodeset; /* Display driver is setting mode */
u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */
struct timer_list vblank_disable_timer; struct timer_list vblank_disable_timer;
u32 max_vblank_count; /**< size of vblank counter register */ u32 max_vblank_count; /**< size of vblank counter register */
......
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