Rev 5078 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 6296 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /************************************************************************** |
1 | /************************************************************************** |
2 | * |
2 | * |
3 | * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA |
3 | * Copyright © 2009-2015 VMware, Inc., Palo Alto, CA., USA |
4 | * All Rights Reserved. |
4 | * All Rights Reserved. |
5 | * |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
7 | * copy of this software and associated documentation files (the |
7 | * copy of this software and associated documentation files (the |
8 | * "Software"), to deal in the Software without restriction, including |
8 | * "Software"), to deal in the Software without restriction, including |
Line 26... | Line 26... | ||
26 | **************************************************************************/ |
26 | **************************************************************************/ |
Line 27... | Line 27... | ||
27 | 27 | ||
28 | #include |
28 | #include |
Line 29... | Line -... | ||
29 | #include "vmwgfx_drv.h" |
- | |
30 | - | ||
31 | #define TASK_INTERRUPTIBLE 1 |
- | |
32 | #define TASK_UNINTERRUPTIBLE 2 |
29 | #include "vmwgfx_drv.h" |
Line 33... | Line 30... | ||
33 | 30 | ||
34 | #define VMW_FENCE_WRAP (1 << 24) |
31 | #define VMW_FENCE_WRAP (1 << 24) |
35 | 32 | ||
36 | irqreturn_t vmw_irq_handler(int irq, void *arg) |
33 | irqreturn_t vmw_irq_handler(int irq, void *arg) |
37 | { |
34 | { |
Line 38... | Line -... | ||
38 | struct drm_device *dev = (struct drm_device *)arg; |
- | |
39 | struct vmw_private *dev_priv = vmw_priv(dev); |
35 | struct drm_device *dev = (struct drm_device *)arg; |
40 | uint32_t status, masked_status; |
36 | struct vmw_private *dev_priv = vmw_priv(dev); |
41 | - | ||
Line 42... | Line 37... | ||
42 | spin_lock(&dev_priv->irq_lock); |
37 | uint32_t status, masked_status; |
43 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
38 | |
Line 44... | Line 39... | ||
44 | masked_status = status & dev_priv->irq_mask; |
39 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
45 | spin_unlock(&dev_priv->irq_lock); |
40 | masked_status = status & READ_ONCE(dev_priv->irq_mask); |
Line 46... | Line 41... | ||
46 | 41 | ||
47 | if (likely(status)) |
42 | if (likely(status)) |
48 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
43 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
Line 63... | Line 58... | ||
63 | return IRQ_HANDLED; |
58 | return IRQ_HANDLED; |
64 | } |
59 | } |
Line 65... | Line 60... | ||
65 | 60 | ||
66 | static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno) |
61 | static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno) |
67 | { |
- | |
68 | uint32_t busy; |
- | |
69 | - | ||
70 | mutex_lock(&dev_priv->hw_mutex); |
- | |
71 | busy = vmw_read(dev_priv, SVGA_REG_BUSY); |
- | |
Line 72... | Line 62... | ||
72 | mutex_unlock(&dev_priv->hw_mutex); |
62 | { |
73 | 63 | ||
Line 74... | Line 64... | ||
74 | return (busy == 0); |
64 | return (vmw_read(dev_priv, SVGA_REG_BUSY) == 0); |
75 | } |
65 | } |
76 | 66 | ||
77 | void vmw_update_seqno(struct vmw_private *dev_priv, |
67 | void vmw_update_seqno(struct vmw_private *dev_priv, |
78 | struct vmw_fifo_state *fifo_state) |
68 | struct vmw_fifo_state *fifo_state) |
Line 79... | Line 69... | ||
79 | { |
69 | { |
80 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
70 | u32 *fifo_mem = dev_priv->mmio_virt; |
81 | uint32_t seqno = ioread32(fifo_mem + SVGA_FIFO_FENCE); |
71 | uint32_t seqno = vmw_mmio_read(fifo_mem + SVGA_FIFO_FENCE); |
82 | 72 | ||
Line 165... | Line 155... | ||
165 | delay(1); |
155 | delay(1); |
166 | } |
156 | } |
167 | } |
157 | } |
168 | // finish_wait(&dev_priv->fence_queue, &__wait); |
158 | // finish_wait(&dev_priv->fence_queue, &__wait); |
169 | if (ret == 0 && fifo_idle) { |
159 | if (ret == 0 && fifo_idle) { |
170 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
160 | u32 *fifo_mem = dev_priv->mmio_virt; |
- | 161 | ||
171 | iowrite32(signal_seq, fifo_mem + SVGA_FIFO_FENCE); |
162 | vmw_mmio_write(signal_seq, fifo_mem + SVGA_FIFO_FENCE); |
172 | } |
163 | } |
173 | wake_up_all(&dev_priv->fence_queue); |
164 | wake_up_all(&dev_priv->fence_queue); |
174 | // if (fifo_idle) |
165 | // if (fifo_idle) |
175 | // up_read(&fifo_state->rwsem); |
166 | // up_read(&fifo_state->rwsem); |
Line 176... | Line 167... | ||
176 | 167 | ||
177 | return ret; |
168 | return ret; |
Line 178... | Line 169... | ||
178 | } |
169 | } |
- | 170 | ||
179 | 171 | void vmw_generic_waiter_add(struct vmw_private *dev_priv, |
|
180 | void vmw_seqno_waiter_add(struct vmw_private *dev_priv) |
172 | u32 flag, int *waiter_count) |
181 | { |
173 | { |
182 | mutex_lock(&dev_priv->hw_mutex); |
- | |
183 | if (dev_priv->fence_queue_waiters++ == 0) { |
- | |
184 | unsigned long irq_flags; |
- | |
185 | - | ||
186 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
174 | spin_lock(&dev_priv->waiter_lock); |
187 | outl(SVGA_IRQFLAG_ANY_FENCE, |
175 | if ((*waiter_count)++ == 0) { |
188 | dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
176 | outl(flag, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
189 | dev_priv->irq_mask |= SVGA_IRQFLAG_ANY_FENCE; |
- | |
190 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
177 | dev_priv->irq_mask |= flag; |
191 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
178 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
192 | } |
179 | } |
Line 193... | Line 180... | ||
193 | mutex_unlock(&dev_priv->hw_mutex); |
180 | spin_unlock(&dev_priv->waiter_lock); |
- | 181 | } |
|
194 | } |
182 | |
195 | 183 | void vmw_generic_waiter_remove(struct vmw_private *dev_priv, |
|
196 | void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) |
184 | u32 flag, int *waiter_count) |
197 | { |
- | |
198 | mutex_lock(&dev_priv->hw_mutex); |
- | |
199 | if (--dev_priv->fence_queue_waiters == 0) { |
- | |
200 | unsigned long irq_flags; |
185 | { |
201 | 186 | spin_lock(&dev_priv->waiter_lock); |
|
202 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
- | |
203 | dev_priv->irq_mask &= ~SVGA_IRQFLAG_ANY_FENCE; |
187 | if (--(*waiter_count) == 0) { |
204 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
188 | dev_priv->irq_mask &= ~flag; |
205 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
189 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
Line -... | Line 190... | ||
- | 190 | } |
|
- | 191 | spin_unlock(&dev_priv->waiter_lock); |
|
- | 192 | } |
|
- | 193 | ||
- | 194 | void vmw_seqno_waiter_add(struct vmw_private *dev_priv) |
|
Line 206... | Line 195... | ||
206 | } |
195 | { |
207 | mutex_unlock(&dev_priv->hw_mutex); |
196 | vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_ANY_FENCE, |
208 | } |
197 | &dev_priv->fence_queue_waiters); |
209 | 198 | } |
|
210 | - | ||
211 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) |
- | |
212 | { |
- | |
213 | mutex_lock(&dev_priv->hw_mutex); |
- | |
214 | if (dev_priv->goal_queue_waiters++ == 0) { |
- | |
215 | unsigned long irq_flags; |
- | |
216 | - | ||
217 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
- | |
218 | outl(SVGA_IRQFLAG_FENCE_GOAL, |
199 | |
- | 200 | void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) |
|
- | 201 | { |
|
- | 202 | vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_ANY_FENCE, |
|
- | 203 | &dev_priv->fence_queue_waiters); |
|
219 | dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
204 | } |
220 | dev_priv->irq_mask |= SVGA_IRQFLAG_FENCE_GOAL; |
205 | |
Line 221... | Line 206... | ||
221 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
206 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) |
222 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
207 | { |
223 | } |
208 | vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_FENCE_GOAL, |
224 | mutex_unlock(&dev_priv->hw_mutex); |
209 | &dev_priv->goal_queue_waiters); |
225 | } |
- | |
226 | - | ||
227 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) |
- | |
228 | { |
- | |
229 | mutex_lock(&dev_priv->hw_mutex); |
- | |
230 | if (--dev_priv->goal_queue_waiters == 0) { |
- | |
231 | unsigned long irq_flags; |
- | |
232 | - | ||
233 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
210 | } |
Line 234... | Line 211... | ||
234 | dev_priv->irq_mask &= ~SVGA_IRQFLAG_FENCE_GOAL; |
211 | |
235 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
212 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) |
236 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
213 | { |
Line 290... | Line 267... | ||
290 | uint32_t status; |
267 | uint32_t status; |
Line 291... | Line 268... | ||
291 | 268 | ||
292 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) |
269 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) |
Line 293... | Line -... | ||
293 | return; |
- | |
294 | 270 | return; |
|
295 | spin_lock_init(&dev_priv->irq_lock); |
271 | |
296 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
272 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
Line 297... | Line 273... | ||
297 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
273 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
Line 308... | Line 284... | ||
308 | uint32_t status; |
284 | uint32_t status; |
Line 309... | Line 285... | ||
309 | 285 | ||
310 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) |
286 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) |
Line 311... | Line -... | ||
311 | return; |
- | |
312 | 287 | return; |
|
313 | mutex_lock(&dev_priv->hw_mutex); |
- | |
Line 314... | Line 288... | ||
314 | vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); |
288 | |
315 | mutex_unlock(&dev_priv->hw_mutex); |
289 | vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); |
316 | 290 | ||
317 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
- | |
318 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
- | |
319 | } |
- | |
320 | - | ||
321 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) |
- | |
322 | { |
- | |
323 | list_del_init(&wait->task_list); |
- |