drm/vmwgfx: Add "quirk" to handling command verification exceptions
[linux-2.6-block.git] / drivers / gpu / drm / vmwgfx / vmwgfx_scrn.c
1 /**************************************************************************
2  *
3  * Copyright © 2011-2014 VMware, Inc., Palo Alto, CA., USA
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27
28 #include "vmwgfx_kms.h"
29 #include <drm/drm_plane_helper.h>
30
31
32 #define vmw_crtc_to_sou(x) \
33         container_of(x, struct vmw_screen_object_unit, base.crtc)
34 #define vmw_encoder_to_sou(x) \
35         container_of(x, struct vmw_screen_object_unit, base.encoder)
36 #define vmw_connector_to_sou(x) \
37         container_of(x, struct vmw_screen_object_unit, base.connector)
38
39 struct vmw_screen_object_display {
40         unsigned num_implicit;
41
42         struct vmw_framebuffer *implicit_fb;
43 };
44
45 /**
46  * Display unit using screen objects.
47  */
48 struct vmw_screen_object_unit {
49         struct vmw_display_unit base;
50
51         unsigned long buffer_size; /**< Size of allocated buffer */
52         struct vmw_dma_buffer *buffer; /**< Backing store buffer */
53
54         bool defined;
55         bool active_implicit;
56 };
57
58 static void vmw_sou_destroy(struct vmw_screen_object_unit *sou)
59 {
60         vmw_du_cleanup(&sou->base);
61         kfree(sou);
62 }
63
64
65 /*
66  * Screen Object Display Unit CRTC functions
67  */
68
69 static void vmw_sou_crtc_destroy(struct drm_crtc *crtc)
70 {
71         vmw_sou_destroy(vmw_crtc_to_sou(crtc));
72 }
73
74 static void vmw_sou_del_active(struct vmw_private *vmw_priv,
75                                struct vmw_screen_object_unit *sou)
76 {
77         struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
78
79         if (sou->active_implicit) {
80                 if (--(ld->num_implicit) == 0)
81                         ld->implicit_fb = NULL;
82                 sou->active_implicit = false;
83         }
84 }
85
86 static void vmw_sou_add_active(struct vmw_private *vmw_priv,
87                                struct vmw_screen_object_unit *sou,
88                                struct vmw_framebuffer *vfb)
89 {
90         struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
91
92         BUG_ON(!ld->num_implicit && ld->implicit_fb);
93
94         if (!sou->active_implicit && sou->base.is_implicit) {
95                 ld->implicit_fb = vfb;
96                 sou->active_implicit = true;
97                 ld->num_implicit++;
98         }
99 }
100
101 /**
102  * Send the fifo command to create a screen.
103  */
104 static int vmw_sou_fifo_create(struct vmw_private *dev_priv,
105                                struct vmw_screen_object_unit *sou,
106                                uint32_t x, uint32_t y,
107                                struct drm_display_mode *mode)
108 {
109         size_t fifo_size;
110
111         struct {
112                 struct {
113                         uint32_t cmdType;
114                 } header;
115                 SVGAScreenObject obj;
116         } *cmd;
117
118         BUG_ON(!sou->buffer);
119
120         fifo_size = sizeof(*cmd);
121         cmd = vmw_fifo_reserve(dev_priv, fifo_size);
122         /* The hardware has hung, nothing we can do about it here. */
123         if (unlikely(cmd == NULL)) {
124                 DRM_ERROR("Fifo reserve failed.\n");
125                 return -ENOMEM;
126         }
127
128         memset(cmd, 0, fifo_size);
129         cmd->header.cmdType = SVGA_CMD_DEFINE_SCREEN;
130         cmd->obj.structSize = sizeof(SVGAScreenObject);
131         cmd->obj.id = sou->base.unit;
132         cmd->obj.flags = SVGA_SCREEN_HAS_ROOT |
133                 (sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0);
134         cmd->obj.size.width = mode->hdisplay;
135         cmd->obj.size.height = mode->vdisplay;
136         if (sou->base.is_implicit) {
137                 cmd->obj.root.x = x;
138                 cmd->obj.root.y = y;
139         } else {
140                 cmd->obj.root.x = sou->base.gui_x;
141                 cmd->obj.root.y = sou->base.gui_y;
142         }
143
144         /* Ok to assume that buffer is pinned in vram */
145         vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr);
146         cmd->obj.backingStore.pitch = mode->hdisplay * 4;
147
148         vmw_fifo_commit(dev_priv, fifo_size);
149
150         sou->defined = true;
151
152         return 0;
153 }
154
155 /**
156  * Send the fifo command to destroy a screen.
157  */
158 static int vmw_sou_fifo_destroy(struct vmw_private *dev_priv,
159                                 struct vmw_screen_object_unit *sou)
160 {
161         size_t fifo_size;
162         int ret;
163
164         struct {
165                 struct {
166                         uint32_t cmdType;
167                 } header;
168                 SVGAFifoCmdDestroyScreen body;
169         } *cmd;
170
171         /* no need to do anything */
172         if (unlikely(!sou->defined))
173                 return 0;
174
175         fifo_size = sizeof(*cmd);
176         cmd = vmw_fifo_reserve(dev_priv, fifo_size);
177         /* the hardware has hung, nothing we can do about it here */
178         if (unlikely(cmd == NULL)) {
179                 DRM_ERROR("Fifo reserve failed.\n");
180                 return -ENOMEM;
181         }
182
183         memset(cmd, 0, fifo_size);
184         cmd->header.cmdType = SVGA_CMD_DESTROY_SCREEN;
185         cmd->body.screenId = sou->base.unit;
186
187         vmw_fifo_commit(dev_priv, fifo_size);
188
189         /* Force sync */
190         ret = vmw_fallback_wait(dev_priv, false, true, 0, false, 3*HZ);
191         if (unlikely(ret != 0))
192                 DRM_ERROR("Failed to sync with HW");
193         else
194                 sou->defined = false;
195
196         return ret;
197 }
198
199 /**
200  * Free the backing store.
201  */
202 static void vmw_sou_backing_free(struct vmw_private *dev_priv,
203                                  struct vmw_screen_object_unit *sou)
204 {
205         struct ttm_buffer_object *bo;
206
207         if (unlikely(sou->buffer == NULL))
208                 return;
209
210         bo = &sou->buffer->base;
211         ttm_bo_unref(&bo);
212         sou->buffer = NULL;
213         sou->buffer_size = 0;
214 }
215
216 /**
217  * Allocate the backing store for the buffer.
218  */
219 static int vmw_sou_backing_alloc(struct vmw_private *dev_priv,
220                                  struct vmw_screen_object_unit *sou,
221                                  unsigned long size)
222 {
223         int ret;
224
225         if (sou->buffer_size == size)
226                 return 0;
227
228         if (sou->buffer)
229                 vmw_sou_backing_free(dev_priv, sou);
230
231         sou->buffer = kzalloc(sizeof(*sou->buffer), GFP_KERNEL);
232         if (unlikely(sou->buffer == NULL))
233                 return -ENOMEM;
234
235         /* After we have alloced the backing store might not be able to
236          * resume the overlays, this is preferred to failing to alloc.
237          */
238         vmw_overlay_pause_all(dev_priv);
239         ret = vmw_dmabuf_init(dev_priv, sou->buffer, size,
240                               &vmw_vram_ne_placement,
241                               false, &vmw_dmabuf_bo_free);
242         vmw_overlay_resume_all(dev_priv);
243
244         if (unlikely(ret != 0))
245                 sou->buffer = NULL; /* vmw_dmabuf_init frees on error */
246         else
247                 sou->buffer_size = size;
248
249         return ret;
250 }
251
252 static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
253 {
254         struct vmw_private *dev_priv;
255         struct vmw_screen_object_unit *sou;
256         struct drm_connector *connector;
257         struct drm_display_mode *mode;
258         struct drm_encoder *encoder;
259         struct vmw_framebuffer *vfb;
260         struct drm_framebuffer *fb;
261         struct drm_crtc *crtc;
262         int ret = 0;
263
264         if (!set)
265                 return -EINVAL;
266
267         if (!set->crtc)
268                 return -EINVAL;
269
270         /* get the sou */
271         crtc = set->crtc;
272         sou = vmw_crtc_to_sou(crtc);
273         vfb = set->fb ? vmw_framebuffer_to_vfb(set->fb) : NULL;
274         dev_priv = vmw_priv(crtc->dev);
275
276         if (set->num_connectors > 1) {
277                 DRM_ERROR("Too many connectors\n");
278                 return -EINVAL;
279         }
280
281         if (set->num_connectors == 1 &&
282             set->connectors[0] != &sou->base.connector) {
283                 DRM_ERROR("Connector doesn't match %p %p\n",
284                         set->connectors[0], &sou->base.connector);
285                 return -EINVAL;
286         }
287
288         /* sou only supports one fb active at the time */
289         if (sou->base.is_implicit &&
290             dev_priv->sou_priv->implicit_fb && vfb &&
291             !(dev_priv->sou_priv->num_implicit == 1 &&
292               sou->active_implicit) &&
293             dev_priv->sou_priv->implicit_fb != vfb) {
294                 DRM_ERROR("Multiple framebuffers not supported\n");
295                 return -EINVAL;
296         }
297
298         /* since they always map one to one these are safe */
299         connector = &sou->base.connector;
300         encoder = &sou->base.encoder;
301
302         /* should we turn the crtc off */
303         if (set->num_connectors == 0 || !set->mode || !set->fb) {
304                 ret = vmw_sou_fifo_destroy(dev_priv, sou);
305                 /* the hardware has hung don't do anything more */
306                 if (unlikely(ret != 0))
307                         return ret;
308
309                 connector->encoder = NULL;
310                 encoder->crtc = NULL;
311                 crtc->primary->fb = NULL;
312                 crtc->x = 0;
313                 crtc->y = 0;
314                 crtc->enabled = false;
315
316                 vmw_sou_del_active(dev_priv, sou);
317
318                 vmw_sou_backing_free(dev_priv, sou);
319
320                 return 0;
321         }
322
323
324         /* we now know we want to set a mode */
325         mode = set->mode;
326         fb = set->fb;
327
328         if (set->x + mode->hdisplay > fb->width ||
329             set->y + mode->vdisplay > fb->height) {
330                 DRM_ERROR("set outside of framebuffer\n");
331                 return -EINVAL;
332         }
333
334         vmw_fb_off(dev_priv);
335         vmw_svga_enable(dev_priv);
336
337         if (mode->hdisplay != crtc->mode.hdisplay ||
338             mode->vdisplay != crtc->mode.vdisplay) {
339                 /* no need to check if depth is different, because backing
340                  * store depth is forced to 4 by the device.
341                  */
342
343                 ret = vmw_sou_fifo_destroy(dev_priv, sou);
344                 /* the hardware has hung don't do anything more */
345                 if (unlikely(ret != 0))
346                         return ret;
347
348                 vmw_sou_backing_free(dev_priv, sou);
349         }
350
351         if (!sou->buffer) {
352                 /* forced to depth 4 by the device */
353                 size_t size = mode->hdisplay * mode->vdisplay * 4;
354                 ret = vmw_sou_backing_alloc(dev_priv, sou, size);
355                 if (unlikely(ret != 0))
356                         return ret;
357         }
358
359         ret = vmw_sou_fifo_create(dev_priv, sou, set->x, set->y, mode);
360         if (unlikely(ret != 0)) {
361                 /*
362                  * We are in a bit of a situation here, the hardware has
363                  * hung and we may or may not have a buffer hanging of
364                  * the screen object, best thing to do is not do anything
365                  * if we where defined, if not just turn the crtc of.
366                  * Not what userspace wants but it needs to htfu.
367                  */
368                 if (sou->defined)
369                         return ret;
370
371                 connector->encoder = NULL;
372                 encoder->crtc = NULL;
373                 crtc->primary->fb = NULL;
374                 crtc->x = 0;
375                 crtc->y = 0;
376                 crtc->enabled = false;
377
378                 return ret;
379         }
380
381         vmw_sou_add_active(dev_priv, sou, vfb);
382
383         connector->encoder = encoder;
384         encoder->crtc = crtc;
385         crtc->mode = *mode;
386         crtc->primary->fb = fb;
387         crtc->x = set->x;
388         crtc->y = set->y;
389         crtc->enabled = true;
390
391         return 0;
392 }
393
394 /**
395  * Returns if this unit can be page flipped.
396  * Must be called with the mode_config mutex held.
397  */
398 static bool vmw_sou_screen_object_flippable(struct vmw_private *dev_priv,
399                                             struct drm_crtc *crtc)
400 {
401         struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
402
403         if (!sou->base.is_implicit)
404                 return true;
405
406         if (dev_priv->sou_priv->num_implicit != 1)
407                 return false;
408
409         return true;
410 }
411
412 /**
413  * Update the implicit fb to the current fb of this crtc.
414  * Must be called with the mode_config mutex held.
415  */
416 void vmw_sou_update_implicit_fb(struct vmw_private *dev_priv,
417                                 struct drm_crtc *crtc)
418 {
419         struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
420
421         BUG_ON(!sou->base.is_implicit);
422
423         dev_priv->sou_priv->implicit_fb =
424                 vmw_framebuffer_to_vfb(sou->base.crtc.primary->fb);
425 }
426
427 static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
428                                   struct drm_framebuffer *fb,
429                                   struct drm_pending_vblank_event *event,
430                                   uint32_t flags)
431 {
432         struct vmw_private *dev_priv = vmw_priv(crtc->dev);
433         struct drm_framebuffer *old_fb = crtc->primary->fb;
434         struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
435         struct drm_file *file_priv = event->base.file_priv;
436         struct vmw_fence_obj *fence = NULL;
437         struct drm_clip_rect clips;
438         int ret;
439
440         /* require ScreenObject support for page flipping */
441         if (!dev_priv->sou_priv)
442                 return -ENOSYS;
443
444         if (!vmw_sou_screen_object_flippable(dev_priv, crtc))
445                 return -EINVAL;
446
447         crtc->primary->fb = fb;
448
449         /* do a full screen dirty update */
450         clips.x1 = clips.y1 = 0;
451         clips.x2 = fb->width;
452         clips.y2 = fb->height;
453
454         if (vfb->dmabuf)
455                 ret = vmw_kms_sou_do_dmabuf_dirty(file_priv, dev_priv, vfb,
456                                                   0, 0, &clips, 1, 1, &fence);
457         else
458                 ret = vmw_kms_sou_do_surface_dirty(dev_priv, file_priv, vfb,
459                                                    0, 0, &clips, 1, 1, &fence);
460
461
462         if (ret != 0)
463                 goto out_no_fence;
464         if (!fence) {
465                 ret = -EINVAL;
466                 goto out_no_fence;
467         }
468
469         ret = vmw_event_fence_action_queue(file_priv, fence,
470                                            &event->base,
471                                            &event->event.tv_sec,
472                                            &event->event.tv_usec,
473                                            true);
474
475         /*
476          * No need to hold on to this now. The only cleanup
477          * we need to do if we fail is unref the fence.
478          */
479         vmw_fence_obj_unreference(&fence);
480
481         if (vmw_crtc_to_du(crtc)->is_implicit)
482                 vmw_sou_update_implicit_fb(dev_priv, crtc);
483
484         return ret;
485
486 out_no_fence:
487         crtc->primary->fb = old_fb;
488         return ret;
489 }
490
491 int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
492                                  struct drm_file *file_priv,
493                                  struct vmw_framebuffer *framebuffer,
494                                  unsigned flags, unsigned color,
495                                  struct drm_clip_rect *clips,
496                                  unsigned num_clips, int inc,
497                                  struct vmw_fence_obj **out_fence)
498 {
499         struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
500         struct drm_clip_rect *clips_ptr;
501         struct drm_clip_rect *tmp;
502         struct drm_crtc *crtc;
503         size_t fifo_size;
504         int i, num_units;
505         int ret = 0; /* silence warning */
506         int left, right, top, bottom;
507
508         struct {
509                 SVGA3dCmdHeader header;
510                 SVGA3dCmdBlitSurfaceToScreen body;
511         } *cmd;
512         SVGASignedRect *blits;
513
514         num_units = 0;
515         list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list,
516                             head) {
517                 if (crtc->primary->fb != &framebuffer->base)
518                         continue;
519                 units[num_units++] = vmw_crtc_to_du(crtc);
520         }
521
522         BUG_ON(!clips || !num_clips);
523
524         tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL);
525         if (unlikely(tmp == NULL)) {
526                 DRM_ERROR("Temporary cliprect memory alloc failed.\n");
527                 return -ENOMEM;
528         }
529
530         fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips;
531         cmd = kzalloc(fifo_size, GFP_KERNEL);
532         if (unlikely(cmd == NULL)) {
533                 DRM_ERROR("Temporary fifo memory alloc failed.\n");
534                 ret = -ENOMEM;
535                 goto out_free_tmp;
536         }
537
538         /* setup blits pointer */
539         blits = (SVGASignedRect *)&cmd[1];
540
541         /* initial clip region */
542         left = clips->x1;
543         right = clips->x2;
544         top = clips->y1;
545         bottom = clips->y2;
546
547         /* skip the first clip rect */
548         for (i = 1, clips_ptr = clips + inc;
549              i < num_clips; i++, clips_ptr += inc) {
550                 left = min_t(int, left, (int)clips_ptr->x1);
551                 right = max_t(int, right, (int)clips_ptr->x2);
552                 top = min_t(int, top, (int)clips_ptr->y1);
553                 bottom = max_t(int, bottom, (int)clips_ptr->y2);
554         }
555
556         /* only need to do this once */
557         cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
558         cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
559
560         cmd->body.srcRect.left = left;
561         cmd->body.srcRect.right = right;
562         cmd->body.srcRect.top = top;
563         cmd->body.srcRect.bottom = bottom;
564
565         clips_ptr = clips;
566         for (i = 0; i < num_clips; i++, clips_ptr += inc) {
567                 tmp[i].x1 = clips_ptr->x1 - left;
568                 tmp[i].x2 = clips_ptr->x2 - left;
569                 tmp[i].y1 = clips_ptr->y1 - top;
570                 tmp[i].y2 = clips_ptr->y2 - top;
571         }
572
573         /* do per unit writing, reuse fifo for each */
574         for (i = 0; i < num_units; i++) {
575                 struct vmw_display_unit *unit = units[i];
576                 struct vmw_clip_rect clip;
577                 int num;
578
579                 clip.x1 = left - unit->crtc.x;
580                 clip.y1 = top - unit->crtc.y;
581                 clip.x2 = right - unit->crtc.x;
582                 clip.y2 = bottom - unit->crtc.y;
583
584                 /* skip any crtcs that misses the clip region */
585                 if (clip.x1 >= unit->crtc.mode.hdisplay ||
586                     clip.y1 >= unit->crtc.mode.vdisplay ||
587                     clip.x2 <= 0 || clip.y2 <= 0)
588                         continue;
589
590                 /*
591                  * In order for the clip rects to be correctly scaled
592                  * the src and dest rects needs to be the same size.
593                  */
594                 cmd->body.destRect.left = clip.x1;
595                 cmd->body.destRect.right = clip.x2;
596                 cmd->body.destRect.top = clip.y1;
597                 cmd->body.destRect.bottom = clip.y2;
598
599                 /* create a clip rect of the crtc in dest coords */
600                 clip.x2 = unit->crtc.mode.hdisplay - clip.x1;
601                 clip.y2 = unit->crtc.mode.vdisplay - clip.y1;
602                 clip.x1 = 0 - clip.x1;
603                 clip.y1 = 0 - clip.y1;
604
605                 /* need to reset sid as it is changed by execbuf */
606                 cmd->body.srcImage.sid = cpu_to_le32(framebuffer->user_handle);
607                 cmd->body.destScreenId = unit->unit;
608
609                 /* clip and write blits to cmd stream */
610                 vmw_clip_cliprects(tmp, num_clips, clip, blits, &num);
611
612                 /* if no cliprects hit skip this */
613                 if (num == 0)
614                         continue;
615
616                 /* only return the last fence */
617                 if (out_fence && *out_fence)
618                         vmw_fence_obj_unreference(out_fence);
619
620                 /* recalculate package length */
621                 fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
622                 cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
623                 ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
624                                           fifo_size, 0, 0, NULL, out_fence);
625
626                 if (unlikely(ret != 0))
627                         break;
628         }
629
630
631         kfree(cmd);
632 out_free_tmp:
633         kfree(tmp);
634
635         return ret;
636 }
637
638 static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
639         .save = vmw_du_crtc_save,
640         .restore = vmw_du_crtc_restore,
641         .cursor_set = vmw_du_crtc_cursor_set,
642         .cursor_move = vmw_du_crtc_cursor_move,
643         .gamma_set = vmw_du_crtc_gamma_set,
644         .destroy = vmw_sou_crtc_destroy,
645         .set_config = vmw_sou_crtc_set_config,
646         .page_flip = vmw_sou_crtc_page_flip,
647 };
648
649 /*
650  * Screen Object Display Unit encoder functions
651  */
652
653 static void vmw_sou_encoder_destroy(struct drm_encoder *encoder)
654 {
655         vmw_sou_destroy(vmw_encoder_to_sou(encoder));
656 }
657
658 static struct drm_encoder_funcs vmw_screen_object_encoder_funcs = {
659         .destroy = vmw_sou_encoder_destroy,
660 };
661
662 /*
663  * Screen Object Display Unit connector functions
664  */
665
666 static void vmw_sou_connector_destroy(struct drm_connector *connector)
667 {
668         vmw_sou_destroy(vmw_connector_to_sou(connector));
669 }
670
671 static struct drm_connector_funcs vmw_sou_connector_funcs = {
672         .dpms = vmw_du_connector_dpms,
673         .save = vmw_du_connector_save,
674         .restore = vmw_du_connector_restore,
675         .detect = vmw_du_connector_detect,
676         .fill_modes = vmw_du_connector_fill_modes,
677         .set_property = vmw_du_connector_set_property,
678         .destroy = vmw_sou_connector_destroy,
679 };
680
681 static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
682 {
683         struct vmw_screen_object_unit *sou;
684         struct drm_device *dev = dev_priv->dev;
685         struct drm_connector *connector;
686         struct drm_encoder *encoder;
687         struct drm_crtc *crtc;
688
689         sou = kzalloc(sizeof(*sou), GFP_KERNEL);
690         if (!sou)
691                 return -ENOMEM;
692
693         sou->base.unit = unit;
694         crtc = &sou->base.crtc;
695         encoder = &sou->base.encoder;
696         connector = &sou->base.connector;
697
698         sou->active_implicit = false;
699
700         sou->base.pref_active = (unit == 0);
701         sou->base.pref_width = dev_priv->initial_width;
702         sou->base.pref_height = dev_priv->initial_height;
703         sou->base.pref_mode = NULL;
704         sou->base.is_implicit = true;
705
706         drm_connector_init(dev, connector, &vmw_sou_connector_funcs,
707                            DRM_MODE_CONNECTOR_VIRTUAL);
708         connector->status = vmw_du_connector_detect(connector, true);
709
710         drm_encoder_init(dev, encoder, &vmw_screen_object_encoder_funcs,
711                          DRM_MODE_ENCODER_VIRTUAL);
712         drm_mode_connector_attach_encoder(connector, encoder);
713         encoder->possible_crtcs = (1 << unit);
714         encoder->possible_clones = 0;
715
716         (void) drm_connector_register(connector);
717
718         drm_crtc_init(dev, crtc, &vmw_screen_object_crtc_funcs);
719
720         drm_mode_crtc_set_gamma_size(crtc, 256);
721
722         drm_object_attach_property(&connector->base,
723                                       dev->mode_config.dirty_info_property,
724                                       1);
725
726         return 0;
727 }
728
729 int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
730 {
731         struct drm_device *dev = dev_priv->dev;
732         int i, ret;
733
734         if (dev_priv->sou_priv) {
735                 DRM_INFO("sou system already on\n");
736                 return -EINVAL;
737         }
738
739         if (!(dev_priv->capabilities & SVGA_CAP_SCREEN_OBJECT_2)) {
740                 DRM_INFO("Not using screen objects,"
741                          " missing cap SCREEN_OBJECT_2\n");
742                 return -ENOSYS;
743         }
744
745         ret = -ENOMEM;
746         dev_priv->sou_priv = kmalloc(sizeof(*dev_priv->sou_priv), GFP_KERNEL);
747         if (unlikely(!dev_priv->sou_priv))
748                 goto err_no_mem;
749
750         dev_priv->sou_priv->num_implicit = 0;
751         dev_priv->sou_priv->implicit_fb = NULL;
752
753         ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS);
754         if (unlikely(ret != 0))
755                 goto err_free;
756
757         ret = drm_mode_create_dirty_info_property(dev);
758         if (unlikely(ret != 0))
759                 goto err_vblank_cleanup;
760
761         for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i)
762                 vmw_sou_init(dev_priv, i);
763
764         dev_priv->active_display_unit = vmw_du_screen_object;
765
766         DRM_INFO("Screen Objects Display Unit initialized\n");
767
768         return 0;
769
770 err_vblank_cleanup:
771         drm_vblank_cleanup(dev);
772 err_free:
773         kfree(dev_priv->sou_priv);
774         dev_priv->sou_priv = NULL;
775 err_no_mem:
776         return ret;
777 }
778
779 int vmw_kms_sou_close_display(struct vmw_private *dev_priv)
780 {
781         struct drm_device *dev = dev_priv->dev;
782
783         if (!dev_priv->sou_priv)
784                 return -ENOSYS;
785
786         drm_vblank_cleanup(dev);
787
788         kfree(dev_priv->sou_priv);
789
790         return 0;
791 }
792
793 static int do_dmabuf_define_gmrfb(struct drm_file *file_priv,
794                                   struct vmw_private *dev_priv,
795                                   struct vmw_framebuffer *framebuffer)
796 {
797         int depth = framebuffer->base.depth;
798         size_t fifo_size;
799         int ret;
800
801         struct {
802                 uint32_t header;
803                 SVGAFifoCmdDefineGMRFB body;
804         } *cmd;
805
806         /* Emulate RGBA support, contrary to svga_reg.h this is not
807          * supported by hosts. This is only a problem if we are reading
808          * this value later and expecting what we uploaded back.
809          */
810         if (depth == 32)
811                 depth = 24;
812
813         fifo_size = sizeof(*cmd);
814         cmd = kmalloc(fifo_size, GFP_KERNEL);
815         if (unlikely(cmd == NULL)) {
816                 DRM_ERROR("Failed to allocate temporary cmd buffer.\n");
817                 return -ENOMEM;
818         }
819
820         memset(cmd, 0, fifo_size);
821         cmd->header = SVGA_CMD_DEFINE_GMRFB;
822         cmd->body.format.bitsPerPixel = framebuffer->base.bits_per_pixel;
823         cmd->body.format.colorDepth = depth;
824         cmd->body.format.reserved = 0;
825         cmd->body.bytesPerLine = framebuffer->base.pitches[0];
826         cmd->body.ptr.gmrId = framebuffer->user_handle;
827         cmd->body.ptr.offset = 0;
828
829         ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
830                                   fifo_size, 0, 0, NULL, NULL);
831
832         kfree(cmd);
833
834         return ret;
835 }
836
837 int vmw_kms_sou_do_dmabuf_dirty(struct drm_file *file_priv,
838                                 struct vmw_private *dev_priv,
839                                 struct vmw_framebuffer *framebuffer,
840                                 unsigned flags, unsigned color,
841                                 struct drm_clip_rect *clips,
842                                 unsigned num_clips, int increment,
843                                 struct vmw_fence_obj **out_fence)
844 {
845         struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
846         struct drm_clip_rect *clips_ptr;
847         int i, k, num_units, ret;
848         struct drm_crtc *crtc;
849         size_t fifo_size;
850
851         struct {
852                 uint32_t header;
853                 SVGAFifoCmdBlitGMRFBToScreen body;
854         } *blits;
855
856         ret = do_dmabuf_define_gmrfb(file_priv, dev_priv, framebuffer);
857         if (unlikely(ret != 0))
858                 return ret; /* define_gmrfb prints warnings */
859
860         fifo_size = sizeof(*blits) * num_clips;
861         blits = kmalloc(fifo_size, GFP_KERNEL);
862         if (unlikely(blits == NULL)) {
863                 DRM_ERROR("Failed to allocate temporary cmd buffer.\n");
864                 return -ENOMEM;
865         }
866
867         num_units = 0;
868         list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
869                 if (crtc->primary->fb != &framebuffer->base)
870                         continue;
871                 units[num_units++] = vmw_crtc_to_du(crtc);
872         }
873
874         for (k = 0; k < num_units; k++) {
875                 struct vmw_display_unit *unit = units[k];
876                 int hit_num = 0;
877
878                 clips_ptr = clips;
879                 for (i = 0; i < num_clips; i++, clips_ptr += increment) {
880                         int clip_x1 = clips_ptr->x1 - unit->crtc.x;
881                         int clip_y1 = clips_ptr->y1 - unit->crtc.y;
882                         int clip_x2 = clips_ptr->x2 - unit->crtc.x;
883                         int clip_y2 = clips_ptr->y2 - unit->crtc.y;
884                         int move_x, move_y;
885
886                         /* skip any crtcs that misses the clip region */
887                         if (clip_x1 >= unit->crtc.mode.hdisplay ||
888                             clip_y1 >= unit->crtc.mode.vdisplay ||
889                             clip_x2 <= 0 || clip_y2 <= 0)
890                                 continue;
891
892                         /* clip size to crtc size */
893                         clip_x2 = min_t(int, clip_x2, unit->crtc.mode.hdisplay);
894                         clip_y2 = min_t(int, clip_y2, unit->crtc.mode.vdisplay);
895
896                         /* translate both src and dest to bring clip into screen */
897                         move_x = min_t(int, clip_x1, 0);
898                         move_y = min_t(int, clip_y1, 0);
899
900                         /* actual translate done here */
901                         blits[hit_num].header = SVGA_CMD_BLIT_GMRFB_TO_SCREEN;
902                         blits[hit_num].body.destScreenId = unit->unit;
903                         blits[hit_num].body.srcOrigin.x = clips_ptr->x1 - move_x;
904                         blits[hit_num].body.srcOrigin.y = clips_ptr->y1 - move_y;
905                         blits[hit_num].body.destRect.left = clip_x1 - move_x;
906                         blits[hit_num].body.destRect.top = clip_y1 - move_y;
907                         blits[hit_num].body.destRect.right = clip_x2;
908                         blits[hit_num].body.destRect.bottom = clip_y2;
909                         hit_num++;
910                 }
911
912                 /* no clips hit the crtc */
913                 if (hit_num == 0)
914                         continue;
915
916                 /* only return the last fence */
917                 if (out_fence && *out_fence)
918                         vmw_fence_obj_unreference(out_fence);
919
920                 fifo_size = sizeof(*blits) * hit_num;
921                 ret = vmw_execbuf_process(file_priv, dev_priv, NULL, blits,
922                                           fifo_size, 0, 0, NULL, out_fence);
923
924                 if (unlikely(ret != 0))
925                         break;
926         }
927
928         kfree(blits);
929
930         return ret;
931 }
932