diff options
Diffstat (limited to 'drivers/char/drm/via_irq.c')
-rw-r--r-- | drivers/char/drm/via_irq.c | 81 |
1 files changed, 34 insertions, 47 deletions
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index f1ab6fc7c07e..c6bb978a1106 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c | |||
@@ -92,17 +92,8 @@ static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1}; | |||
92 | static unsigned time_diff(struct timeval *now, struct timeval *then) | 92 | static unsigned time_diff(struct timeval *now, struct timeval *then) |
93 | { | 93 | { |
94 | return (now->tv_usec >= then->tv_usec) ? | 94 | return (now->tv_usec >= then->tv_usec) ? |
95 | now->tv_usec - then->tv_usec : | 95 | now->tv_usec - then->tv_usec : |
96 | 1000000 - (then->tv_usec - now->tv_usec); | 96 | 1000000 - (then->tv_usec - now->tv_usec); |
97 | } | ||
98 | |||
99 | u32 via_get_vblank_counter(struct drm_device *dev, int crtc) | ||
100 | { | ||
101 | drm_via_private_t *dev_priv = dev->dev_private; | ||
102 | if (crtc != 0) | ||
103 | return 0; | ||
104 | |||
105 | return atomic_read(&dev_priv->vbl_received); | ||
106 | } | 97 | } |
107 | 98 | ||
108 | irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | 99 | irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) |
@@ -117,8 +108,8 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
117 | 108 | ||
118 | status = VIA_READ(VIA_REG_INTERRUPT); | 109 | status = VIA_READ(VIA_REG_INTERRUPT); |
119 | if (status & VIA_IRQ_VBLANK_PENDING) { | 110 | if (status & VIA_IRQ_VBLANK_PENDING) { |
120 | atomic_inc(&dev_priv->vbl_received); | 111 | atomic_inc(&dev->vbl_received); |
121 | if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) { | 112 | if (!(atomic_read(&dev->vbl_received) & 0x0F)) { |
122 | do_gettimeofday(&cur_vblank); | 113 | do_gettimeofday(&cur_vblank); |
123 | if (dev_priv->last_vblank_valid) { | 114 | if (dev_priv->last_vblank_valid) { |
124 | dev_priv->usec_per_vblank = | 115 | dev_priv->usec_per_vblank = |
@@ -128,11 +119,12 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS) | |||
128 | dev_priv->last_vblank = cur_vblank; | 119 | dev_priv->last_vblank = cur_vblank; |
129 | dev_priv->last_vblank_valid = 1; | 120 | dev_priv->last_vblank_valid = 1; |
130 | } | 121 | } |
131 | if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) { | 122 | if (!(atomic_read(&dev->vbl_received) & 0xFF)) { |
132 | DRM_DEBUG("US per vblank is: %u\n", | 123 | DRM_DEBUG("US per vblank is: %u\n", |
133 | dev_priv->usec_per_vblank); | 124 | dev_priv->usec_per_vblank); |
134 | } | 125 | } |
135 | drm_handle_vblank(dev, 0); | 126 | DRM_WAKEUP(&dev->vbl_queue); |
127 | drm_vbl_send_signals(dev); | ||
136 | handled = 1; | 128 | handled = 1; |
137 | } | 129 | } |
138 | 130 | ||
@@ -171,34 +163,31 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv) | |||
171 | } | 163 | } |
172 | } | 164 | } |
173 | 165 | ||
174 | int via_enable_vblank(struct drm_device *dev, int crtc) | 166 | int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence) |
175 | { | 167 | { |
176 | drm_via_private_t *dev_priv = dev->dev_private; | 168 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
177 | u32 status; | 169 | unsigned int cur_vblank; |
170 | int ret = 0; | ||
178 | 171 | ||
179 | if (crtc != 0) { | 172 | DRM_DEBUG("\n"); |
180 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); | 173 | if (!dev_priv) { |
174 | DRM_ERROR("called with no initialization\n"); | ||
181 | return -EINVAL; | 175 | return -EINVAL; |
182 | } | 176 | } |
183 | 177 | ||
184 | status = VIA_READ(VIA_REG_INTERRUPT); | 178 | viadrv_acknowledge_irqs(dev_priv); |
185 | VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); | ||
186 | 179 | ||
187 | VIA_WRITE8(0x83d4, 0x11); | 180 | /* Assume that the user has missed the current sequence number |
188 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | 181 | * by about a day rather than she wants to wait for years |
182 | * using vertical blanks... | ||
183 | */ | ||
189 | 184 | ||
190 | return 0; | 185 | DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ, |
191 | } | 186 | (((cur_vblank = atomic_read(&dev->vbl_received)) - |
187 | *sequence) <= (1 << 23))); | ||
192 | 188 | ||
193 | void via_disable_vblank(struct drm_device *dev, int crtc) | 189 | *sequence = cur_vblank; |
194 | { | 190 | return ret; |
195 | drm_via_private_t *dev_priv = dev->dev_private; | ||
196 | |||
197 | VIA_WRITE8(0x83d4, 0x11); | ||
198 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); | ||
199 | |||
200 | if (crtc != 0) | ||
201 | DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc); | ||
202 | } | 191 | } |
203 | 192 | ||
204 | static int | 193 | static int |
@@ -303,25 +292,23 @@ void via_driver_irq_preinstall(struct drm_device * dev) | |||
303 | } | 292 | } |
304 | } | 293 | } |
305 | 294 | ||
306 | int via_driver_irq_postinstall(struct drm_device * dev) | 295 | void via_driver_irq_postinstall(struct drm_device * dev) |
307 | { | 296 | { |
308 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 297 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
309 | u32 status; | 298 | u32 status; |
310 | 299 | ||
311 | DRM_DEBUG("via_driver_irq_postinstall\n"); | 300 | DRM_DEBUG("\n"); |
312 | if (!dev_priv) | 301 | if (dev_priv) { |
313 | return -EINVAL; | 302 | status = VIA_READ(VIA_REG_INTERRUPT); |
303 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | ||
304 | | dev_priv->irq_enable_mask); | ||
314 | 305 | ||
315 | drm_vblank_init(dev, 1); | 306 | /* Some magic, oh for some data sheets ! */ |
316 | status = VIA_READ(VIA_REG_INTERRUPT); | ||
317 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL | ||
318 | | dev_priv->irq_enable_mask); | ||
319 | 307 | ||
320 | /* Some magic, oh for some data sheets ! */ | 308 | VIA_WRITE8(0x83d4, 0x11); |
321 | VIA_WRITE8(0x83d4, 0x11); | 309 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); |
322 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | ||
323 | 310 | ||
324 | return 0; | 311 | } |
325 | } | 312 | } |
326 | 313 | ||
327 | void via_driver_irq_uninstall(struct drm_device * dev) | 314 | void via_driver_irq_uninstall(struct drm_device * dev) |