aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-11-27 23:22:24 -0500
committerDave Airlie <airlied@linux.ie>2008-12-29 02:47:22 -0500
commit7c1c2871a6a3a114853ec6836e9035ac1c0c7f7a (patch)
tree1b5debcc86ff20bd5e11b42ea5c52da42214e376 /drivers/gpu/drm/i915/i915_irq.c
parente7f7ab45ebcb54fd5f814ea15ea079e079662f67 (diff)
drm: move to kref per-master structures.
This is step one towards having multiple masters sharing a drm device in order to get fast-user-switching to work. It splits out the information associated with the drm master into a separate kref counted structure, and allocates this when a master opens the device node. It also allows the current master to abdicate (say while VT switched), and a new master to take over the hardware. It moves the Intel and radeon drivers to using the sarea from within the new master structures. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 69b9a42da95e..9b673d2f912b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -168,6 +168,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
168{ 168{
169 struct drm_device *dev = (struct drm_device *) arg; 169 struct drm_device *dev = (struct drm_device *) arg;
170 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 170 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
171 struct drm_i915_master_private *master_priv;
171 u32 iir, new_iir; 172 u32 iir, new_iir;
172 u32 pipea_stats, pipeb_stats; 173 u32 pipea_stats, pipeb_stats;
173 u32 vblank_status; 174 u32 vblank_status;
@@ -222,9 +223,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
222 I915_WRITE(IIR, iir); 223 I915_WRITE(IIR, iir);
223 new_iir = I915_READ(IIR); /* Flush posted writes */ 224 new_iir = I915_READ(IIR); /* Flush posted writes */
224 225
225 if (dev_priv->sarea_priv) 226 if (dev->primary->master) {
226 dev_priv->sarea_priv->last_dispatch = 227 master_priv = dev->primary->master->driver_priv;
227 READ_BREADCRUMB(dev_priv); 228 if (master_priv->sarea_priv)
229 master_priv->sarea_priv->last_dispatch =
230 READ_BREADCRUMB(dev_priv);
231 }
228 232
229 if (iir & I915_USER_INTERRUPT) { 233 if (iir & I915_USER_INTERRUPT) {
230 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); 234 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
@@ -269,6 +273,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
269static int i915_emit_irq(struct drm_device * dev) 273static int i915_emit_irq(struct drm_device * dev)
270{ 274{
271 drm_i915_private_t *dev_priv = dev->dev_private; 275 drm_i915_private_t *dev_priv = dev->dev_private;
276 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
272 RING_LOCALS; 277 RING_LOCALS;
273 278
274 i915_kernel_lost_context(dev); 279 i915_kernel_lost_context(dev);
@@ -278,8 +283,8 @@ static int i915_emit_irq(struct drm_device * dev)
278 dev_priv->counter++; 283 dev_priv->counter++;
279 if (dev_priv->counter > 0x7FFFFFFFUL) 284 if (dev_priv->counter > 0x7FFFFFFFUL)
280 dev_priv->counter = 1; 285 dev_priv->counter = 1;
281 if (dev_priv->sarea_priv) 286 if (master_priv->sarea_priv)
282 dev_priv->sarea_priv->last_enqueue = dev_priv->counter; 287 master_priv->sarea_priv->last_enqueue = dev_priv->counter;
283 288
284 BEGIN_LP_RING(4); 289 BEGIN_LP_RING(4);
285 OUT_RING(MI_STORE_DWORD_INDEX); 290 OUT_RING(MI_STORE_DWORD_INDEX);
@@ -317,21 +322,20 @@ void i915_user_irq_put(struct drm_device *dev)
317static int i915_wait_irq(struct drm_device * dev, int irq_nr) 322static int i915_wait_irq(struct drm_device * dev, int irq_nr)
318{ 323{
319 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 324 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
325 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
320 int ret = 0; 326 int ret = 0;
321 327
322 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr, 328 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
323 READ_BREADCRUMB(dev_priv)); 329 READ_BREADCRUMB(dev_priv));
324 330
325 if (READ_BREADCRUMB(dev_priv) >= irq_nr) { 331 if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
326 if (dev_priv->sarea_priv) { 332 if (master_priv->sarea_priv)
327 dev_priv->sarea_priv->last_dispatch = 333 master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
328 READ_BREADCRUMB(dev_priv);
329 }
330 return 0; 334 return 0;
331 } 335 }
332 336
333 if (dev_priv->sarea_priv) 337 if (master_priv->sarea_priv)
334 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 338 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
335 339
336 i915_user_irq_get(dev); 340 i915_user_irq_get(dev);
337 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ, 341 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
@@ -343,10 +347,6 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
343 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); 347 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
344 } 348 }
345 349
346 if (dev_priv->sarea_priv)
347 dev_priv->sarea_priv->last_dispatch =
348 READ_BREADCRUMB(dev_priv);
349
350 return ret; 350 return ret;
351} 351}
352 352