1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <linux/sched/signal.h>
29
30#include <drm/ttm/ttm_placement.h>
31
32#include "vmwgfx_drv.h"
33#include "vmwgfx_devcaps.h"
34
35bool vmw_supports_3d(struct vmw_private *dev_priv)
36{
37 uint32_t fifo_min, hwversion;
38 const struct vmw_fifo_state *fifo = dev_priv->fifo;
39
40 if (!(dev_priv->capabilities & SVGA_CAP_3D))
41 return false;
42
43 if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) {
44 uint32_t result;
45
46 if (!dev_priv->has_mob)
47 return false;
48
49 result = vmw_devcap_get(dev_priv, SVGA3D_DEVCAP_3D);
50
51 return (result != 0);
52 }
53
54 if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO))
55 return false;
56
57 BUG_ON(vmw_is_svga_v3(dev_priv));
58
59 fifo_min = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MIN);
60 if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int))
61 return false;
62
63 hwversion = vmw_fifo_mem_read(dev_priv,
64 ((fifo->capabilities &
65 SVGA_FIFO_CAP_3D_HWVERSION_REVISED) ?
66 SVGA_FIFO_3D_HWVERSION_REVISED :
67 SVGA_FIFO_3D_HWVERSION));
68
69 if (hwversion == 0)
70 return false;
71
72 if (hwversion < SVGA3D_HWVERSION_WS8_B1)
73 return false;
74
75
76 if (dev_priv->active_display_unit == vmw_du_legacy)
77 return false;
78
79 return true;
80}
81
82bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv)
83{
84 uint32_t caps;
85
86 if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO))
87 return false;
88
89 caps = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_CAPABILITIES);
90 if (caps & SVGA_FIFO_CAP_PITCHLOCK)
91 return true;
92
93 return false;
94}
95
96struct vmw_fifo_state *vmw_fifo_create(struct vmw_private *dev_priv)
97{
98 struct vmw_fifo_state *fifo;
99 uint32_t max;
100 uint32_t min;
101
102 if (!dev_priv->fifo_mem)
103 return NULL;
104
105 fifo = kzalloc(sizeof(*fifo), GFP_KERNEL);
106 if (!fifo)
107 return ERR_PTR(-ENOMEM);
108 fifo->static_buffer_size = VMWGFX_FIFO_STATIC_SIZE;
109 fifo->static_buffer = vmalloc(fifo->static_buffer_size);
110 if (unlikely(fifo->static_buffer == NULL)) {
111 kfree(fifo);
112 return ERR_PTR(-ENOMEM);
113 }
114
115 fifo->dynamic_buffer = NULL;
116 fifo->reserved_size = 0;
117 fifo->using_bounce_buffer = false;
118
119 mutex_init(&fifo->fifo_mutex);
120 init_rwsem(&fifo->rwsem);
121 min = 4;
122 if (dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)
123 min = vmw_read(dev_priv, SVGA_REG_MEM_REGS);
124 min <<= 2;
125
126 if (min < PAGE_SIZE)
127 min = PAGE_SIZE;
128
129 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_MIN, min);
130 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_MAX, dev_priv->fifo_mem_size);
131 wmb();
132 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_NEXT_CMD, min);
133 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_STOP, min);
134 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_BUSY, 0);
135 mb();
136
137 vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1);
138
139 max = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MAX);
140 min = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MIN);
141 fifo->capabilities = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_CAPABILITIES);
142
143 drm_info(&dev_priv->drm,
144 "Fifo max 0x%08x min 0x%08x cap 0x%08x\n",
145 (unsigned int) max,
146 (unsigned int) min,
147 (unsigned int) fifo->capabilities);
148
149 if (unlikely(min >= max)) {
150 drm_warn(&dev_priv->drm,
151 "FIFO memory is not usable. Driver failed to initialize.");
152 return ERR_PTR(-ENXIO);
153 }
154
155 return fifo;
156}
157
158void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason)
159{
160 u32 *fifo_mem = dev_priv->fifo_mem;
161 if (fifo_mem && cmpxchg(fifo_mem + SVGA_FIFO_BUSY, 0, 1) == 0)
162 vmw_write(dev_priv, SVGA_REG_SYNC, reason);
163
164}
165
166void vmw_fifo_destroy(struct vmw_private *dev_priv)
167{
168 struct vmw_fifo_state *fifo = dev_priv->fifo;
169
170 if (!fifo)
171 return;
172
173 if (likely(fifo->static_buffer != NULL)) {
174 vfree(fifo->static_buffer);
175 fifo->static_buffer = NULL;
176 }
177
178 if (likely(fifo->dynamic_buffer != NULL)) {
179 vfree(fifo->dynamic_buffer);
180 fifo->dynamic_buffer = NULL;
181 }
182 kfree(fifo);
183 dev_priv->fifo = NULL;
184}
185
186static bool vmw_fifo_is_full(struct vmw_private *dev_priv, uint32_t bytes)
187{
188 uint32_t max = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MAX);
189 uint32_t next_cmd = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_NEXT_CMD);
190 uint32_t min = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MIN);
191 uint32_t stop = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_STOP);
192
193 return ((max - next_cmd) + (stop - min) <= bytes);
194}
195
196static int vmw_fifo_wait_noirq(struct vmw_private *dev_priv,
197 uint32_t bytes, bool interruptible,
198 unsigned long timeout)
199{
200 int ret = 0;
201 unsigned long end_jiffies = jiffies + timeout;
202 DEFINE_WAIT(__wait);
203
204 DRM_INFO("Fifo wait noirq.\n");
205
206 for (;;) {
207 prepare_to_wait(&dev_priv->fifo_queue, &__wait,
208 (interruptible) ?
209 TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
210 if (!vmw_fifo_is_full(dev_priv, bytes))
211 break;
212 if (time_after_eq(jiffies, end_jiffies)) {
213 ret = -EBUSY;
214 DRM_ERROR("SVGA device lockup.\n");
215 break;
216 }
217 schedule_timeout(1);
218 if (interruptible && signal_pending(current)) {
219 ret = -ERESTARTSYS;
220 break;
221 }
222 }
223 finish_wait(&dev_priv->fifo_queue, &__wait);
224 wake_up_all(&dev_priv->fifo_queue);
225 DRM_INFO("Fifo noirq exit.\n");
226 return ret;
227}
228
229static int vmw_fifo_wait(struct vmw_private *dev_priv,
230 uint32_t bytes, bool interruptible,
231 unsigned long timeout)
232{
233 long ret = 1L;
234
235 if (likely(!vmw_fifo_is_full(dev_priv, bytes)))
236 return 0;
237
238 vmw_fifo_ping_host(dev_priv, SVGA_SYNC_FIFOFULL);
239 if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
240 return vmw_fifo_wait_noirq(dev_priv, bytes,
241 interruptible, timeout);
242
243 vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_FIFO_PROGRESS,
244 &dev_priv->fifo_queue_waiters);
245
246 if (interruptible)
247 ret = wait_event_interruptible_timeout
248 (dev_priv->fifo_queue,
249 !vmw_fifo_is_full(dev_priv, bytes), timeout);
250 else
251 ret = wait_event_timeout
252 (dev_priv->fifo_queue,
253 !vmw_fifo_is_full(dev_priv, bytes), timeout);
254
255 if (unlikely(ret == 0))
256 ret = -EBUSY;
257 else if (likely(ret > 0))
258 ret = 0;
259
260 vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_FIFO_PROGRESS,
261 &dev_priv->fifo_queue_waiters);
262
263 return ret;
264}
265
266
267
268
269
270
271
272
273
274
275
276static void *vmw_local_fifo_reserve(struct vmw_private *dev_priv,
277 uint32_t bytes)
278{
279 struct vmw_fifo_state *fifo_state = dev_priv->fifo;
280 u32 *fifo_mem = dev_priv->fifo_mem;
281 uint32_t max;
282 uint32_t min;
283 uint32_t next_cmd;
284 uint32_t reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE;
285 int ret;
286
287 mutex_lock(&fifo_state->fifo_mutex);
288 max = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MAX);
289 min = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MIN);
290 next_cmd = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_NEXT_CMD);
291
292 if (unlikely(bytes >= (max - min)))
293 goto out_err;
294
295 BUG_ON(fifo_state->reserved_size != 0);
296 BUG_ON(fifo_state->dynamic_buffer != NULL);
297
298 fifo_state->reserved_size = bytes;
299
300 while (1) {
301 uint32_t stop = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_STOP);
302 bool need_bounce = false;
303 bool reserve_in_place = false;
304
305 if (next_cmd >= stop) {
306 if (likely((next_cmd + bytes < max ||
307 (next_cmd + bytes == max && stop > min))))
308 reserve_in_place = true;
309
310 else if (vmw_fifo_is_full(dev_priv, bytes)) {
311 ret = vmw_fifo_wait(dev_priv, bytes,
312 false, 3 * HZ);
313 if (unlikely(ret != 0))
314 goto out_err;
315 } else
316 need_bounce = true;
317
318 } else {
319
320 if (likely((next_cmd + bytes < stop)))
321 reserve_in_place = true;
322 else {
323 ret = vmw_fifo_wait(dev_priv, bytes,
324 false, 3 * HZ);
325 if (unlikely(ret != 0))
326 goto out_err;
327 }
328 }
329
330 if (reserve_in_place) {
331 if (reserveable || bytes <= sizeof(uint32_t)) {
332 fifo_state->using_bounce_buffer = false;
333
334 if (reserveable)
335 vmw_fifo_mem_write(dev_priv,
336 SVGA_FIFO_RESERVED,
337 bytes);
338 return (void __force *) (fifo_mem +
339 (next_cmd >> 2));
340 } else {
341 need_bounce = true;
342 }
343 }
344
345 if (need_bounce) {
346 fifo_state->using_bounce_buffer = true;
347 if (bytes < fifo_state->static_buffer_size)
348 return fifo_state->static_buffer;
349 else {
350 fifo_state->dynamic_buffer = vmalloc(bytes);
351 if (!fifo_state->dynamic_buffer)
352 goto out_err;
353 return fifo_state->dynamic_buffer;
354 }
355 }
356 }
357out_err:
358 fifo_state->reserved_size = 0;
359 mutex_unlock(&fifo_state->fifo_mutex);
360
361 return NULL;
362}
363
364void *vmw_cmd_ctx_reserve(struct vmw_private *dev_priv, uint32_t bytes,
365 int ctx_id)
366{
367 void *ret;
368
369 if (dev_priv->cman)
370 ret = vmw_cmdbuf_reserve(dev_priv->cman, bytes,
371 ctx_id, false, NULL);
372 else if (ctx_id == SVGA3D_INVALID_ID)
373 ret = vmw_local_fifo_reserve(dev_priv, bytes);
374 else {
375 WARN(1, "Command buffer has not been allocated.\n");
376 ret = NULL;
377 }
378 if (IS_ERR_OR_NULL(ret))
379 return NULL;
380
381 return ret;
382}
383
384static void vmw_fifo_res_copy(struct vmw_fifo_state *fifo_state,
385 struct vmw_private *vmw,
386 uint32_t next_cmd,
387 uint32_t max, uint32_t min, uint32_t bytes)
388{
389 u32 *fifo_mem = vmw->fifo_mem;
390 uint32_t chunk_size = max - next_cmd;
391 uint32_t rest;
392 uint32_t *buffer = (fifo_state->dynamic_buffer != NULL) ?
393 fifo_state->dynamic_buffer : fifo_state->static_buffer;
394
395 if (bytes < chunk_size)
396 chunk_size = bytes;
397
398 vmw_fifo_mem_write(vmw, SVGA_FIFO_RESERVED, bytes);
399 mb();
400 memcpy(fifo_mem + (next_cmd >> 2), buffer, chunk_size);
401 rest = bytes - chunk_size;
402 if (rest)
403 memcpy(fifo_mem + (min >> 2), buffer + (chunk_size >> 2), rest);
404}
405
406static void vmw_fifo_slow_copy(struct vmw_fifo_state *fifo_state,
407 struct vmw_private *vmw,
408 uint32_t next_cmd,
409 uint32_t max, uint32_t min, uint32_t bytes)
410{
411 uint32_t *buffer = (fifo_state->dynamic_buffer != NULL) ?
412 fifo_state->dynamic_buffer : fifo_state->static_buffer;
413
414 while (bytes > 0) {
415 vmw_fifo_mem_write(vmw, (next_cmd >> 2), *buffer++);
416 next_cmd += sizeof(uint32_t);
417 if (unlikely(next_cmd == max))
418 next_cmd = min;
419 mb();
420 vmw_fifo_mem_write(vmw, SVGA_FIFO_NEXT_CMD, next_cmd);
421 mb();
422 bytes -= sizeof(uint32_t);
423 }
424}
425
426static void vmw_local_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes)
427{
428 struct vmw_fifo_state *fifo_state = dev_priv->fifo;
429 uint32_t next_cmd = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_NEXT_CMD);
430 uint32_t max = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MAX);
431 uint32_t min = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MIN);
432 bool reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE;
433
434 BUG_ON((bytes & 3) != 0);
435 BUG_ON(bytes > fifo_state->reserved_size);
436
437 fifo_state->reserved_size = 0;
438
439 if (fifo_state->using_bounce_buffer) {
440 if (reserveable)
441 vmw_fifo_res_copy(fifo_state, dev_priv,
442 next_cmd, max, min, bytes);
443 else
444 vmw_fifo_slow_copy(fifo_state, dev_priv,
445 next_cmd, max, min, bytes);
446
447 if (fifo_state->dynamic_buffer) {
448 vfree(fifo_state->dynamic_buffer);
449 fifo_state->dynamic_buffer = NULL;
450 }
451
452 }
453
454 down_write(&fifo_state->rwsem);
455 if (fifo_state->using_bounce_buffer || reserveable) {
456 next_cmd += bytes;
457 if (next_cmd >= max)
458 next_cmd -= max - min;
459 mb();
460 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_NEXT_CMD, next_cmd);
461 }
462
463 if (reserveable)
464 vmw_fifo_mem_write(dev_priv, SVGA_FIFO_RESERVED, 0);
465 mb();
466 up_write(&fifo_state->rwsem);
467 vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
468 mutex_unlock(&fifo_state->fifo_mutex);
469}
470
471void vmw_cmd_commit(struct vmw_private *dev_priv, uint32_t bytes)
472{
473 if (dev_priv->cman)
474 vmw_cmdbuf_commit(dev_priv->cman, bytes, NULL, false);
475 else
476 vmw_local_fifo_commit(dev_priv, bytes);
477}
478
479
480
481
482
483
484
485
486void vmw_cmd_commit_flush(struct vmw_private *dev_priv, uint32_t bytes)
487{
488 if (dev_priv->cman)
489 vmw_cmdbuf_commit(dev_priv->cman, bytes, NULL, true);
490 else
491 vmw_local_fifo_commit(dev_priv, bytes);
492}
493
494
495
496
497
498
499
500
501int vmw_cmd_flush(struct vmw_private *dev_priv, bool interruptible)
502{
503 might_sleep();
504
505 if (dev_priv->cman)
506 return vmw_cmdbuf_cur_flush(dev_priv->cman, interruptible);
507 else
508 return 0;
509}
510
511int vmw_cmd_send_fence(struct vmw_private *dev_priv, uint32_t *seqno)
512{
513 struct svga_fifo_cmd_fence *cmd_fence;
514 u32 *fm;
515 int ret = 0;
516 uint32_t bytes = sizeof(u32) + sizeof(*cmd_fence);
517
518 fm = VMW_CMD_RESERVE(dev_priv, bytes);
519 if (unlikely(fm == NULL)) {
520 *seqno = atomic_read(&dev_priv->marker_seq);
521 ret = -ENOMEM;
522 (void)vmw_fallback_wait(dev_priv, false, true, *seqno,
523 false, 3*HZ);
524 goto out_err;
525 }
526
527 do {
528 *seqno = atomic_add_return(1, &dev_priv->marker_seq);
529 } while (*seqno == 0);
530
531 if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE)) {
532
533
534
535
536
537
538 vmw_cmd_commit(dev_priv, 0);
539 return 0;
540 }
541
542 *fm++ = SVGA_CMD_FENCE;
543 cmd_fence = (struct svga_fifo_cmd_fence *) fm;
544 cmd_fence->fence = *seqno;
545 vmw_cmd_commit_flush(dev_priv, bytes);
546 vmw_update_seqno(dev_priv);
547
548out_err:
549 return ret;
550}
551
552
553
554
555
556
557
558
559
560
561static int vmw_cmd_emit_dummy_legacy_query(struct vmw_private *dev_priv,
562 uint32_t cid)
563{
564
565
566
567
568
569
570 struct ttm_buffer_object *bo = &dev_priv->dummy_query_bo->base;
571 struct {
572 SVGA3dCmdHeader header;
573 SVGA3dCmdWaitForQuery body;
574 } *cmd;
575
576 cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
577 if (unlikely(cmd == NULL))
578 return -ENOMEM;
579
580 cmd->header.id = SVGA_3D_CMD_WAIT_FOR_QUERY;
581 cmd->header.size = sizeof(cmd->body);
582 cmd->body.cid = cid;
583 cmd->body.type = SVGA3D_QUERYTYPE_OCCLUSION;
584
585 if (bo->resource->mem_type == TTM_PL_VRAM) {
586 cmd->body.guestResult.gmrId = SVGA_GMR_FRAMEBUFFER;
587 cmd->body.guestResult.offset = bo->resource->start << PAGE_SHIFT;
588 } else {
589 cmd->body.guestResult.gmrId = bo->resource->start;
590 cmd->body.guestResult.offset = 0;
591 }
592
593 vmw_cmd_commit(dev_priv, sizeof(*cmd));
594
595 return 0;
596}
597
598
599
600
601
602
603
604
605
606
607static int vmw_cmd_emit_dummy_gb_query(struct vmw_private *dev_priv,
608 uint32_t cid)
609{
610
611
612
613
614
615
616 struct ttm_buffer_object *bo = &dev_priv->dummy_query_bo->base;
617 struct {
618 SVGA3dCmdHeader header;
619 SVGA3dCmdWaitForGBQuery body;
620 } *cmd;
621
622 cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
623 if (unlikely(cmd == NULL))
624 return -ENOMEM;
625
626 cmd->header.id = SVGA_3D_CMD_WAIT_FOR_GB_QUERY;
627 cmd->header.size = sizeof(cmd->body);
628 cmd->body.cid = cid;
629 cmd->body.type = SVGA3D_QUERYTYPE_OCCLUSION;
630 BUG_ON(bo->resource->mem_type != VMW_PL_MOB);
631 cmd->body.mobid = bo->resource->start;
632 cmd->body.offset = 0;
633
634 vmw_cmd_commit(dev_priv, sizeof(*cmd));
635
636 return 0;
637}
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658int vmw_cmd_emit_dummy_query(struct vmw_private *dev_priv,
659 uint32_t cid)
660{
661 if (dev_priv->has_mob)
662 return vmw_cmd_emit_dummy_gb_query(dev_priv, cid);
663
664 return vmw_cmd_emit_dummy_legacy_query(dev_priv, cid);
665}
666
667
668
669
670
671
672
673
674
675
676bool vmw_cmd_supported(struct vmw_private *vmw)
677{
678 if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
679 SVGA_CAP_CMD_BUFFERS_2)) != 0)
680 return true;
681
682
683
684 return vmw->fifo_mem != NULL;
685}
686