aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/mga_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/mga_irq.c')
-rw-r--r--drivers/char/drm/mga_irq.c69
1 files changed, 18 insertions, 51 deletions
diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c
index 06852fb4b27..9302cb8f0f8 100644
--- a/drivers/char/drm/mga_irq.c
+++ b/drivers/char/drm/mga_irq.c
@@ -35,20 +35,6 @@
35#include "mga_drm.h" 35#include "mga_drm.h"
36#include "mga_drv.h" 36#include "mga_drv.h"
37 37
38u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
39{
40 const drm_mga_private_t *const dev_priv =
41 (drm_mga_private_t *) dev->dev_private;
42
43 if (crtc != 0) {
44 return 0;
45 }
46
47
48 return atomic_read(&dev_priv->vbl_received);
49}
50
51
52irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS) 38irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
53{ 39{
54 struct drm_device *dev = (struct drm_device *) arg; 40 struct drm_device *dev = (struct drm_device *) arg;
@@ -61,8 +47,9 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
61 /* VBLANK interrupt */ 47 /* VBLANK interrupt */
62 if (status & MGA_VLINEPEN) { 48 if (status & MGA_VLINEPEN) {
63 MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR); 49 MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
64 atomic_inc(&dev_priv->vbl_received); 50 atomic_inc(&dev->vbl_received);
65 drm_handle_vblank(dev, 0); 51 DRM_WAKEUP(&dev->vbl_queue);
52 drm_vbl_send_signals(dev);
66 handled = 1; 53 handled = 1;
67 } 54 }
68 55
@@ -91,34 +78,22 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
91 return IRQ_NONE; 78 return IRQ_NONE;
92} 79}
93 80
94int mga_enable_vblank(struct drm_device *dev, int crtc) 81int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
95{ 82{
96 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; 83 unsigned int cur_vblank;
97 84 int ret = 0;
98 if (crtc != 0) {
99 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
100 crtc);
101 return 0;
102 }
103
104 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
105 return 0;
106}
107 85
86 /* Assume that the user has missed the current sequence number
87 * by about a day rather than she wants to wait for years
88 * using vertical blanks...
89 */
90 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
91 (((cur_vblank = atomic_read(&dev->vbl_received))
92 - *sequence) <= (1 << 23)));
108 93
109void mga_disable_vblank(struct drm_device *dev, int crtc) 94 *sequence = cur_vblank;
110{
111 if (crtc != 0) {
112 DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
113 crtc);
114 }
115 95
116 /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have 96 return ret;
117 * a nice hardware counter that tracks the number of refreshes when
118 * the interrupt is disabled, and the kernel doesn't know the refresh
119 * rate to calculate an estimate.
120 */
121 /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
122} 97}
123 98
124int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence) 99int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
@@ -150,22 +125,14 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
150 MGA_WRITE(MGA_ICLEAR, ~0); 125 MGA_WRITE(MGA_ICLEAR, ~0);
151} 126}
152 127
153int mga_driver_irq_postinstall(struct drm_device * dev) 128void mga_driver_irq_postinstall(struct drm_device * dev)
154{ 129{
155 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private; 130 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
156 int ret;
157
158 ret = drm_vblank_init(dev, 1);
159 if (ret)
160 return ret;
161 131
162 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue); 132 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
163 133
164 /* Turn on soft trap interrupt. Vertical blank interrupts are enabled 134 /* Turn on vertical blank interrupt and soft trap interrupt. */
165 * in mga_enable_vblank. 135 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
166 */
167 MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
168 return 0;
169} 136}
170 137
171void mga_driver_irq_uninstall(struct drm_device * dev) 138void mga_driver_irq_uninstall(struct drm_device * dev)