diff options
author | Dave Airlie <airlied@redhat.com> | 2008-11-27 23:22:24 -0500 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2008-12-29 02:47:22 -0500 |
commit | 7c1c2871a6a3a114853ec6836e9035ac1c0c7f7a (patch) | |
tree | 1b5debcc86ff20bd5e11b42ea5c52da42214e376 /drivers/gpu/drm/i915/i915_irq.c | |
parent | e7f7ab45ebcb54fd5f814ea15ea079e079662f67 (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.c | 30 |
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) | |||
269 | static int i915_emit_irq(struct drm_device * dev) | 273 | static 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) | |||
317 | static int i915_wait_irq(struct drm_device * dev, int irq_nr) | 322 | static 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 | ||