diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/char/drm/i915_irq.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/char/drm/i915_irq.c')
-rw-r--r-- | drivers/char/drm/i915_irq.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c new file mode 100644 index 000000000000..b0239262a84a --- /dev/null +++ b/drivers/char/drm/i915_irq.c | |||
@@ -0,0 +1,161 @@ | |||
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 | |||
19 | irqreturn_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 | |||
39 | int 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 | |||
59 | int 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 | */ | ||
87 | int 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 | */ | ||
116 | int 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 | */ | ||
135 | void 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 | |||
144 | void 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 | |||
152 | void 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 | } | ||