PageRenderTime 24ms CodeModel.GetById 11ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/char/drm/i915_irq.c

https://bitbucket.org/evzijst/gittest
C | 161 lines | 109 code | 38 blank | 14 comment | 9 complexity | be96ce4f65c5f663f1a12e6ac22dbb84 MD5 | raw file
  1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
  2 */
  3/**************************************************************************
  4 * 
  5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  6 * All Rights Reserved.
  7 * 
  8 **************************************************************************/
  9
 10#include "drmP.h"
 11#include "drm.h"
 12#include "i915_drm.h"
 13#include "i915_drv.h"
 14
 15#define USER_INT_FLAG 0x2
 16#define MAX_NOPID ((u32)~0)
 17#define READ_BREADCRUMB(dev_priv)  (((u32*)(dev_priv->hw_status_page))[5])
 18
 19irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 20{
 21	drm_device_t *dev = (drm_device_t *) arg;
 22	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 23	u16 temp;
 24
 25	temp = I915_READ16(I915REG_INT_IDENTITY_R);
 26	temp &= USER_INT_FLAG;
 27
 28	DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
 29
 30	if (temp == 0)
 31		return IRQ_NONE;
 32
 33	I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
 34	DRM_WAKEUP(&dev_priv->irq_queue);
 35
 36	return IRQ_HANDLED;
 37}
 38
 39int i915_emit_irq(drm_device_t * dev)
 40{
 41	drm_i915_private_t *dev_priv = dev->dev_private;
 42	u32 ret;
 43	RING_LOCALS;
 44
 45	i915_kernel_lost_context(dev);
 46
 47	DRM_DEBUG("%s\n", __FUNCTION__);
 48
 49	ret = dev_priv->counter;
 50
 51	BEGIN_LP_RING(2);
 52	OUT_RING(0);
 53	OUT_RING(GFX_OP_USER_INTERRUPT);
 54	ADVANCE_LP_RING();
 55
 56	return ret;
 57}
 58
 59int i915_wait_irq(drm_device_t * dev, int irq_nr)
 60{
 61	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 62	int ret = 0;
 63
 64	DRM_DEBUG("%s irq_nr=%d breadcrumb=%d\n", __FUNCTION__, irq_nr,
 65		  READ_BREADCRUMB(dev_priv));
 66
 67	if (READ_BREADCRUMB(dev_priv) >= irq_nr)
 68		return 0;
 69
 70	dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
 71
 72	DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
 73		    READ_BREADCRUMB(dev_priv) >= irq_nr);
 74
 75	if (ret == DRM_ERR(EBUSY)) {
 76		DRM_ERROR("%s: EBUSY -- rec: %d emitted: %d\n",
 77			  __FUNCTION__,
 78			  READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
 79	}
 80
 81	dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
 82	return ret;
 83}
 84
 85/* Needs the lock as it touches the ring.
 86 */
 87int i915_irq_emit(DRM_IOCTL_ARGS)
 88{
 89	DRM_DEVICE;
 90	drm_i915_private_t *dev_priv = dev->dev_private;
 91	drm_i915_irq_emit_t emit;
 92	int result;
 93
 94	LOCK_TEST_WITH_RETURN(dev, filp);
 95
 96	if (!dev_priv) {
 97		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
 98		return DRM_ERR(EINVAL);
 99	}
100
101	DRM_COPY_FROM_USER_IOCTL(emit, (drm_i915_irq_emit_t __user *) data,
102				 sizeof(emit));
103
104	result = i915_emit_irq(dev);
105
106	if (DRM_COPY_TO_USER(emit.irq_seq, &result, sizeof(int))) {
107		DRM_ERROR("copy_to_user\n");
108		return DRM_ERR(EFAULT);
109	}
110
111	return 0;
112}
113
114/* Doesn't need the hardware lock.
115 */
116int i915_irq_wait(DRM_IOCTL_ARGS)
117{
118	DRM_DEVICE;
119	drm_i915_private_t *dev_priv = dev->dev_private;
120	drm_i915_irq_wait_t irqwait;
121
122	if (!dev_priv) {
123		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
124		return DRM_ERR(EINVAL);
125	}
126
127	DRM_COPY_FROM_USER_IOCTL(irqwait, (drm_i915_irq_wait_t __user *) data,
128				 sizeof(irqwait));
129
130	return i915_wait_irq(dev, irqwait.irq_seq);
131}
132
133/* drm_dma.h hooks
134*/
135void i915_driver_irq_preinstall(drm_device_t * dev)
136{
137	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
138
139	I915_WRITE16(I915REG_HWSTAM, 0xfffe);
140	I915_WRITE16(I915REG_INT_MASK_R, 0x0);
141	I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
142}
143
144void i915_driver_irq_postinstall(drm_device_t * dev)
145{
146	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
147
148	I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG);
149	DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
150}
151
152void i915_driver_irq_uninstall(drm_device_t * dev)
153{
154	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
155	if (!dev_priv)
156		return;
157
158	I915_WRITE16(I915REG_HWSTAM, 0xffff);
159	I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
160	I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
161}