Subversion Repositories Kolibri OS

Rev

Rev 4569 | Rev 5078 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright © 2009 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.  
  30.  
  31. /* Might need a hrtimer here? */
  32. #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
  33.  
  34.  
  35. struct vmw_clip_rect {
  36.         int x1, x2, y1, y2;
  37. };
  38.  
  39. /**
  40.  * Clip @num_rects number of @rects against @clip storing the
  41.  * results in @out_rects and the number of passed rects in @out_num.
  42.  */
  43. static void vmw_clip_cliprects(struct drm_clip_rect *rects,
  44.                         int num_rects,
  45.                         struct vmw_clip_rect clip,
  46.                         SVGASignedRect *out_rects,
  47.                         int *out_num)
  48. {
  49.         int i, k;
  50.  
  51.         for (i = 0, k = 0; i < num_rects; i++) {
  52.                 int x1 = max_t(int, clip.x1, rects[i].x1);
  53.                 int y1 = max_t(int, clip.y1, rects[i].y1);
  54.                 int x2 = min_t(int, clip.x2, rects[i].x2);
  55.                 int y2 = min_t(int, clip.y2, rects[i].y2);
  56.  
  57.                 if (x1 >= x2)
  58.                         continue;
  59.                 if (y1 >= y2)
  60.                         continue;
  61.  
  62.                 out_rects[k].left   = x1;
  63.                 out_rects[k].top    = y1;
  64.                 out_rects[k].right  = x2;
  65.                 out_rects[k].bottom = y2;
  66.                 k++;
  67.         }
  68.  
  69.         *out_num = k;
  70. }
  71.  
  72. void vmw_display_unit_cleanup(struct vmw_display_unit *du)
  73. {
  74. //   if (du->cursor_surface)
  75. //       vmw_surface_unreference(&du->cursor_surface);
  76. //   if (du->cursor_dmabuf)
  77. //       vmw_dmabuf_unreference(&du->cursor_dmabuf);
  78.         drm_crtc_cleanup(&du->crtc);
  79.         drm_encoder_cleanup(&du->encoder);
  80.         drm_connector_cleanup(&du->connector);
  81. }
  82.  
  83. /*
  84.  * Display Unit Cursor functions
  85.  */
  86.  
  87. int vmw_cursor_update_image(struct vmw_private *dev_priv,
  88.                             u32 *image, u32 width, u32 height,
  89.                             u32 hotspotX, u32 hotspotY)
  90. {
  91.         struct {
  92.                 u32 cmd;
  93.                 SVGAFifoCmdDefineAlphaCursor cursor;
  94.         } *cmd;
  95.         u32 image_size = width * height * 4;
  96.         u32 cmd_size = sizeof(*cmd) + image_size;
  97.     u32 *dst;
  98.     int i, j;
  99.  
  100.         if (!image)
  101.                 return -EINVAL;
  102.  
  103.         cmd = vmw_fifo_reserve(dev_priv, cmd_size);
  104.         if (unlikely(cmd == NULL)) {
  105.                 DRM_ERROR("Fifo reserve failed.\n");
  106.                 return -ENOMEM;
  107.         }
  108.  
  109.         memset(cmd, 0, sizeof(*cmd));
  110.  
  111.     dst = (u32*)&cmd[1];
  112.  
  113.     for(i = 0; i < 32; i++)
  114.     {
  115.         for(j = 0; j < 32; j++)
  116.             *dst++ = *image++;
  117.         for( ; j < 64; j++)
  118.             *dst++ = 0;
  119.     }
  120.     for(i = 0; i < 64*(64-32); i++)
  121.         *image++ = 0;
  122.  
  123.         cmd->cmd = cpu_to_le32(SVGA_CMD_DEFINE_ALPHA_CURSOR);
  124.         cmd->cursor.id = cpu_to_le32(0);
  125.         cmd->cursor.width = cpu_to_le32(width);
  126.         cmd->cursor.height = cpu_to_le32(height);
  127.         cmd->cursor.hotspotX = cpu_to_le32(hotspotX);
  128.         cmd->cursor.hotspotY = cpu_to_le32(hotspotY);
  129.  
  130.         vmw_fifo_commit(dev_priv, cmd_size);
  131.  
  132.         return 0;
  133. }
  134.  
  135. #if 0
  136. int vmw_cursor_update_dmabuf(struct vmw_private *dev_priv,
  137.                              struct vmw_dma_buffer *dmabuf,
  138.                              u32 width, u32 height,
  139.                              u32 hotspotX, u32 hotspotY)
  140. {
  141.         struct ttm_bo_kmap_obj map;
  142.         unsigned long kmap_offset;
  143.         unsigned long kmap_num;
  144.         void *virtual;
  145.         bool dummy;
  146.         int ret;
  147.  
  148.         kmap_offset = 0;
  149.         kmap_num = (width*height*4 + PAGE_SIZE - 1) >> PAGE_SHIFT;
  150.  
  151.         ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0);
  152.         if (unlikely(ret != 0)) {
  153.                 DRM_ERROR("reserve failed\n");
  154.                 return -EINVAL;
  155.         }
  156.  
  157.         ret = ttm_bo_kmap(&dmabuf->base, kmap_offset, kmap_num, &map);
  158.         if (unlikely(ret != 0))
  159.                 goto err_unreserve;
  160.  
  161.         virtual = ttm_kmap_obj_virtual(&map, &dummy);
  162.         ret = vmw_cursor_update_image(dev_priv, virtual, width, height,
  163.                                       hotspotX, hotspotY);
  164.  
  165.         ttm_bo_kunmap(&map);
  166. err_unreserve:
  167.         ttm_bo_unreserve(&dmabuf->base);
  168.  
  169.         return ret;
  170. }
  171. #endif
  172.  
  173. void vmw_cursor_update_position(struct vmw_private *dev_priv,
  174.                                 bool show, int x, int y)
  175. {
  176.         __le32 __iomem *fifo_mem = dev_priv->mmio_virt;
  177.         uint32_t count;
  178.  
  179.         iowrite32(show ? 1 : 0, fifo_mem + SVGA_FIFO_CURSOR_ON);
  180.         iowrite32(x, fifo_mem + SVGA_FIFO_CURSOR_X);
  181.         iowrite32(y, fifo_mem + SVGA_FIFO_CURSOR_Y);
  182.         count = ioread32(fifo_mem + SVGA_FIFO_CURSOR_COUNT);
  183.         iowrite32(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT);
  184. }
  185.  
  186. #if 0
  187. int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
  188.                            uint32_t handle, uint32_t width, uint32_t height)
  189. {
  190.         struct vmw_private *dev_priv = vmw_priv(crtc->dev);
  191.         struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
  192.         struct vmw_surface *surface = NULL;
  193.         struct vmw_dma_buffer *dmabuf = NULL;
  194.         int ret;
  195.  
  196.         /*
  197.          * FIXME: Unclear whether there's any global state touched by the
  198.          * cursor_set function, especially vmw_cursor_update_position looks
  199.          * suspicious. For now take the easy route and reacquire all locks. We
  200.          * can do this since the caller in the drm core doesn't check anything
  201.          * which is protected by any looks.
  202.          */
  203.         mutex_unlock(&crtc->mutex);
  204.         drm_modeset_lock_all(dev_priv->dev);
  205.  
  206.         /* A lot of the code assumes this */
  207.         if (handle && (width != 64 || height != 64)) {
  208.                 ret = -EINVAL;
  209.                 goto out;
  210.         }
  211.  
  212.         if (handle) {
  213.                 struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
  214.  
  215.                 ret = vmw_user_lookup_handle(dev_priv, tfile,
  216.                                              handle, &surface, &dmabuf);
  217.                 if (ret) {
  218.                         DRM_ERROR("failed to find surface or dmabuf: %i\n", ret);
  219.                         ret = -EINVAL;
  220.                         goto out;
  221.                 }
  222.         }
  223.  
  224.         /* need to do this before taking down old image */
  225.         if (surface && !surface->snooper.image) {
  226.                 DRM_ERROR("surface not suitable for cursor\n");
  227.                 vmw_surface_unreference(&surface);
  228.                 ret = -EINVAL;
  229.                 goto out;
  230.         }
  231.  
  232.         /* takedown old cursor */
  233.         if (du->cursor_surface) {
  234.                 du->cursor_surface->snooper.crtc = NULL;
  235.                 vmw_surface_unreference(&du->cursor_surface);
  236.         }
  237.         if (du->cursor_dmabuf)
  238.                 vmw_dmabuf_unreference(&du->cursor_dmabuf);
  239.  
  240.         /* setup new image */
  241.         if (surface) {
  242.                 /* vmw_user_surface_lookup takes one reference */
  243.                 du->cursor_surface = surface;
  244.  
  245.                 du->cursor_surface->snooper.crtc = crtc;
  246.                 du->cursor_age = du->cursor_surface->snooper.age;
  247.                 vmw_cursor_update_image(dev_priv, surface->snooper.image,
  248.                                         64, 64, du->hotspot_x, du->hotspot_y);
  249.         } else if (dmabuf) {
  250.                 /* vmw_user_surface_lookup takes one reference */
  251.                 du->cursor_dmabuf = dmabuf;
  252.  
  253.                 ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, width, height,
  254.                                                du->hotspot_x, du->hotspot_y);
  255.         } else {
  256.                 vmw_cursor_update_position(dev_priv, false, 0, 0);
  257.                 ret = 0;
  258.                 goto out;
  259.         }
  260.  
  261.         vmw_cursor_update_position(dev_priv, true,
  262.                                    du->cursor_x + du->hotspot_x,
  263.                                    du->cursor_y + du->hotspot_y);
  264.  
  265.         ret = 0;
  266. out:
  267.         drm_modeset_unlock_all(dev_priv->dev);
  268.         mutex_lock(&crtc->mutex);
  269.  
  270.         return ret;
  271. }
  272.  
  273. int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
  274. {
  275.         struct vmw_private *dev_priv = vmw_priv(crtc->dev);
  276.         struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
  277.         bool shown = du->cursor_surface || du->cursor_dmabuf ? true : false;
  278.  
  279.         du->cursor_x = x + crtc->x;
  280.         du->cursor_y = y + crtc->y;
  281.  
  282.         /*
  283.          * FIXME: Unclear whether there's any global state touched by the
  284.          * cursor_set function, especially vmw_cursor_update_position looks
  285.          * suspicious. For now take the easy route and reacquire all locks. We
  286.          * can do this since the caller in the drm core doesn't check anything
  287.          * which is protected by any looks.
  288.          */
  289.         mutex_unlock(&crtc->mutex);
  290.         drm_modeset_lock_all(dev_priv->dev);
  291.  
  292.         vmw_cursor_update_position(dev_priv, shown,
  293.                                    du->cursor_x + du->hotspot_x,
  294.                                    du->cursor_y + du->hotspot_y);
  295.  
  296.         drm_modeset_unlock_all(dev_priv->dev);
  297.         mutex_lock(&crtc->mutex);
  298.  
  299.         return 0;
  300. }
  301.  
  302. void vmw_kms_cursor_snoop(struct vmw_surface *srf,
  303.                           struct ttm_object_file *tfile,
  304.                           struct ttm_buffer_object *bo,
  305.                           SVGA3dCmdHeader *header)
  306. {
  307.         struct ttm_bo_kmap_obj map;
  308.         unsigned long kmap_offset;
  309.         unsigned long kmap_num;
  310.         SVGA3dCopyBox *box;
  311.         unsigned box_count;
  312.         void *virtual;
  313.         bool dummy;
  314.         struct vmw_dma_cmd {
  315.                 SVGA3dCmdHeader header;
  316.                 SVGA3dCmdSurfaceDMA dma;
  317.         } *cmd;
  318.         int i, ret;
  319.  
  320.         cmd = container_of(header, struct vmw_dma_cmd, header);
  321.  
  322.         /* No snooper installed */
  323.         if (!srf->snooper.image)
  324.                 return;
  325.  
  326.         if (cmd->dma.host.face != 0 || cmd->dma.host.mipmap != 0) {
  327.                 DRM_ERROR("face and mipmap for cursors should never != 0\n");
  328.                 return;
  329.         }
  330.  
  331.         if (cmd->header.size < 64) {
  332.                 DRM_ERROR("at least one full copy box must be given\n");
  333.                 return;
  334.         }
  335.  
  336.         box = (SVGA3dCopyBox *)&cmd[1];
  337.         box_count = (cmd->header.size - sizeof(SVGA3dCmdSurfaceDMA)) /
  338.                         sizeof(SVGA3dCopyBox);
  339.  
  340.         if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
  341.             box->x != 0    || box->y != 0    || box->z != 0    ||
  342.             box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
  343.             box->d != 1    || box_count != 1) {
  344.                 /* TODO handle none page aligned offsets */
  345.                 /* TODO handle more dst & src != 0 */
  346.                 /* TODO handle more then one copy */
  347.                 DRM_ERROR("Cant snoop dma request for cursor!\n");
  348.                 DRM_ERROR("(%u, %u, %u) (%u, %u, %u) (%ux%ux%u) %u %u\n",
  349.                           box->srcx, box->srcy, box->srcz,
  350.                           box->x, box->y, box->z,
  351.                           box->w, box->h, box->d, box_count,
  352.                           cmd->dma.guest.ptr.offset);
  353.                 return;
  354.         }
  355.  
  356.         kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
  357.         kmap_num = (64*64*4) >> PAGE_SHIFT;
  358.  
  359.         ret = ttm_bo_reserve(bo, true, false, false, 0);
  360.         if (unlikely(ret != 0)) {
  361.                 DRM_ERROR("reserve failed\n");
  362.                 return;
  363.         }
  364.  
  365.         ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
  366.         if (unlikely(ret != 0))
  367.                 goto err_unreserve;
  368.  
  369.         virtual = ttm_kmap_obj_virtual(&map, &dummy);
  370.  
  371.         if (box->w == 64 && cmd->dma.guest.pitch == 64*4) {
  372.                 memcpy(srf->snooper.image, virtual, 64*64*4);
  373.         } else {
  374.                 /* Image is unsigned pointer. */
  375.                 for (i = 0; i < box->h; i++)
  376.                         memcpy(srf->snooper.image + i * 64,
  377.                                virtual + i * cmd->dma.guest.pitch,
  378.                                box->w * 4);
  379.         }
  380.  
  381.         srf->snooper.age++;
  382.  
  383.         /* we can't call this function from this function since execbuf has
  384.          * reserved fifo space.
  385.          *
  386.          * if (srf->snooper.crtc)
  387.          *      vmw_ldu_crtc_cursor_update_image(dev_priv,
  388.          *                                       srf->snooper.image, 64, 64,
  389.          *                                       du->hotspot_x, du->hotspot_y);
  390.          */
  391.  
  392.         ttm_bo_kunmap(&map);
  393. err_unreserve:
  394.         ttm_bo_unreserve(bo);
  395. }
  396.  
  397. void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
  398. {
  399.         struct drm_device *dev = dev_priv->dev;
  400.         struct vmw_display_unit *du;
  401.         struct drm_crtc *crtc;
  402.  
  403.         mutex_lock(&dev->mode_config.mutex);
  404.  
  405.         list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
  406.                 du = vmw_crtc_to_du(crtc);
  407.                 if (!du->cursor_surface ||
  408.                     du->cursor_age == du->cursor_surface->snooper.age)
  409.                         continue;
  410.  
  411.                 du->cursor_age = du->cursor_surface->snooper.age;
  412.                 vmw_cursor_update_image(dev_priv,
  413.                                         du->cursor_surface->snooper.image,
  414.                                         64, 64, du->hotspot_x, du->hotspot_y);
  415.         }
  416.  
  417.         mutex_unlock(&dev->mode_config.mutex);
  418. }
  419. #endif
  420.  
  421. /*
  422.  * Generic framebuffer code
  423.  */
  424.  
  425. /*
  426.  * Surface framebuffer code
  427.  */
  428.  
  429. #define vmw_framebuffer_to_vfbs(x) \
  430.         container_of(x, struct vmw_framebuffer_surface, base.base)
  431.  
  432. struct vmw_framebuffer_surface {
  433.         struct vmw_framebuffer base;
  434.         struct vmw_surface *surface;
  435.         struct vmw_dma_buffer *buffer;
  436.         struct list_head head;
  437.         struct drm_master *master;
  438. };
  439.  
  440. static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
  441. {
  442.         struct vmw_framebuffer_surface *vfbs =
  443.                 vmw_framebuffer_to_vfbs(framebuffer);
  444.         struct vmw_master *vmaster = vmw_master(vfbs->master);
  445.  
  446.  
  447.         mutex_lock(&vmaster->fb_surf_mutex);
  448.         list_del(&vfbs->head);
  449.         mutex_unlock(&vmaster->fb_surf_mutex);
  450.  
  451.  
  452.         kfree(vfbs);
  453. }
  454.  
  455. static int do_surface_dirty_sou(struct vmw_private *dev_priv,
  456.                                 struct drm_file *file_priv,
  457.                                 struct vmw_framebuffer *framebuffer,
  458.                                 unsigned flags, unsigned color,
  459.                                 struct drm_clip_rect *clips,
  460.                                 unsigned num_clips, int inc,
  461.                                 struct vmw_fence_obj **out_fence)
  462. {
  463.         struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
  464.         struct drm_clip_rect *clips_ptr;
  465.         struct drm_clip_rect *tmp;
  466.         struct drm_crtc *crtc;
  467.         size_t fifo_size;
  468.         int i, num_units;
  469.         int ret = 0; /* silence warning */
  470.         int left, right, top, bottom;
  471.  
  472.         struct {
  473.                 SVGA3dCmdHeader header;
  474.                 SVGA3dCmdBlitSurfaceToScreen body;
  475.         } *cmd;
  476.         SVGASignedRect *blits;
  477.  
  478.         num_units = 0;
  479.         list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list,
  480.                             head) {
  481.                 if (crtc->fb != &framebuffer->base)
  482.                         continue;
  483.                 units[num_units++] = vmw_crtc_to_du(crtc);
  484.         }
  485.  
  486.         BUG_ON(!clips || !num_clips);
  487.  
  488.         tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL);
  489.         if (unlikely(tmp == NULL)) {
  490.                 DRM_ERROR("Temporary cliprect memory alloc failed.\n");
  491.                 return -ENOMEM;
  492.         }
  493.  
  494.         fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips;
  495.         cmd = kzalloc(fifo_size, GFP_KERNEL);
  496.         if (unlikely(cmd == NULL)) {
  497.                 DRM_ERROR("Temporary fifo memory alloc failed.\n");
  498.                 ret = -ENOMEM;
  499.                 goto out_free_tmp;
  500.         }
  501.  
  502.         /* setup blits pointer */
  503.         blits = (SVGASignedRect *)&cmd[1];
  504.  
  505.         /* initial clip region */
  506.         left = clips->x1;
  507.         right = clips->x2;
  508.         top = clips->y1;
  509.         bottom = clips->y2;
  510.  
  511.         /* skip the first clip rect */
  512.         for (i = 1, clips_ptr = clips + inc;
  513.              i < num_clips; i++, clips_ptr += inc) {
  514.                 left = min_t(int, left, (int)clips_ptr->x1);
  515.                 right = max_t(int, right, (int)clips_ptr->x2);
  516.                 top = min_t(int, top, (int)clips_ptr->y1);
  517.                 bottom = max_t(int, bottom, (int)clips_ptr->y2);
  518.         }
  519.  
  520.         /* only need to do this once */
  521.         cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
  522.         cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
  523.  
  524.         cmd->body.srcRect.left = left;
  525.         cmd->body.srcRect.right = right;
  526.         cmd->body.srcRect.top = top;
  527.         cmd->body.srcRect.bottom = bottom;
  528.  
  529.         clips_ptr = clips;
  530.         for (i = 0; i < num_clips; i++, clips_ptr += inc) {
  531.                 tmp[i].x1 = clips_ptr->x1 - left;
  532.                 tmp[i].x2 = clips_ptr->x2 - left;
  533.                 tmp[i].y1 = clips_ptr->y1 - top;
  534.                 tmp[i].y2 = clips_ptr->y2 - top;
  535.         }
  536.  
  537.         /* do per unit writing, reuse fifo for each */
  538.         for (i = 0; i < num_units; i++) {
  539.                 struct vmw_display_unit *unit = units[i];
  540.                 struct vmw_clip_rect clip;
  541.                 int num;
  542.  
  543.                 clip.x1 = left - unit->crtc.x;
  544.                 clip.y1 = top - unit->crtc.y;
  545.                 clip.x2 = right - unit->crtc.x;
  546.                 clip.y2 = bottom - unit->crtc.y;
  547.  
  548.                 /* skip any crtcs that misses the clip region */
  549.                 if (clip.x1 >= unit->crtc.mode.hdisplay ||
  550.                     clip.y1 >= unit->crtc.mode.vdisplay ||
  551.                     clip.x2 <= 0 || clip.y2 <= 0)
  552.                         continue;
  553.  
  554.                 /*
  555.                  * In order for the clip rects to be correctly scaled
  556.                  * the src and dest rects needs to be the same size.
  557.                  */
  558.                 cmd->body.destRect.left = clip.x1;
  559.                 cmd->body.destRect.right = clip.x2;
  560.                 cmd->body.destRect.top = clip.y1;
  561.                 cmd->body.destRect.bottom = clip.y2;
  562.  
  563.                 /* create a clip rect of the crtc in dest coords */
  564.                 clip.x2 = unit->crtc.mode.hdisplay - clip.x1;
  565.                 clip.y2 = unit->crtc.mode.vdisplay - clip.y1;
  566.                 clip.x1 = 0 - clip.x1;
  567.                 clip.y1 = 0 - clip.y1;
  568.  
  569.                 /* need to reset sid as it is changed by execbuf */
  570.                 cmd->body.srcImage.sid = cpu_to_le32(framebuffer->user_handle);
  571.                 cmd->body.destScreenId = unit->unit;
  572.  
  573.                 /* clip and write blits to cmd stream */
  574.                 vmw_clip_cliprects(tmp, num_clips, clip, blits, &num);
  575.  
  576.                 /* if no cliprects hit skip this */
  577.                 if (num == 0)
  578.                         continue;
  579.  
  580.                 /* only return the last fence */
  581.                 if (out_fence && *out_fence)
  582.                         vmw_fence_obj_unreference(out_fence);
  583.  
  584.                 /* recalculate package length */
  585.                 fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
  586.                 cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
  587.                 ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
  588.                                           fifo_size, 0, NULL, out_fence);
  589.  
  590.                 if (unlikely(ret != 0))
  591.                         break;
  592.         }
  593.  
  594.  
  595.         kfree(cmd);
  596. out_free_tmp:
  597.         kfree(tmp);
  598.  
  599.         return ret;
  600. }
  601.  
  602. static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
  603.                                   struct drm_file *file_priv,
  604.                                   unsigned flags, unsigned color,
  605.                                   struct drm_clip_rect *clips,
  606.                                   unsigned num_clips)
  607. {
  608.         struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
  609.         struct vmw_master *vmaster = vmw_master(file_priv->master);
  610.         struct vmw_framebuffer_surface *vfbs =
  611.                 vmw_framebuffer_to_vfbs(framebuffer);
  612.         struct drm_clip_rect norect;
  613.         int ret, inc = 1;
  614.  
  615.         if (unlikely(vfbs->master != file_priv->master))
  616.                 return -EINVAL;
  617.  
  618.         /* Require ScreenObject support for 3D */
  619.         if (!dev_priv->sou_priv)
  620.                 return -EINVAL;
  621.  
  622.         drm_modeset_lock_all(dev_priv->dev);
  623.  
  624.         ret = ttm_read_lock(&vmaster->lock, true);
  625.         if (unlikely(ret != 0)) {
  626.                 drm_modeset_unlock_all(dev_priv->dev);
  627.                 return ret;
  628.         }
  629.  
  630.         if (!num_clips) {
  631.                 num_clips = 1;
  632.                 clips = &norect;
  633.                 norect.x1 = norect.y1 = 0;
  634.                 norect.x2 = framebuffer->width;
  635.                 norect.y2 = framebuffer->height;
  636.         } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
  637.                 num_clips /= 2;
  638.                 inc = 2; /* skip source rects */
  639.         }
  640.  
  641.         ret = do_surface_dirty_sou(dev_priv, file_priv, &vfbs->base,
  642.                                    flags, color,
  643.                                    clips, num_clips, inc, NULL);
  644.  
  645.         ttm_read_unlock(&vmaster->lock);
  646.  
  647.         drm_modeset_unlock_all(dev_priv->dev);
  648.  
  649.         return 0;
  650. }
  651.  
  652. static struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
  653.    .destroy = vmw_framebuffer_surface_destroy,
  654.         .dirty = vmw_framebuffer_surface_dirty,
  655. };
  656.  
  657. static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
  658.                                            struct drm_file *file_priv,
  659.                                            struct vmw_surface *surface,
  660.                                            struct vmw_framebuffer **out,
  661.                                            const struct drm_mode_fb_cmd
  662.                                            *mode_cmd)
  663.  
  664. {
  665.         struct drm_device *dev = dev_priv->dev;
  666.         struct vmw_framebuffer_surface *vfbs;
  667.         enum SVGA3dSurfaceFormat format;
  668.         struct vmw_master *vmaster = vmw_master(file_priv->master);
  669.         int ret;
  670.  
  671.         /* 3D is only supported on HWv8 hosts which supports screen objects */
  672.         if (!dev_priv->sou_priv)
  673.                 return -ENOSYS;
  674.  
  675.         /*
  676.          * Sanity checks.
  677.          */
  678.  
  679.         /* Surface must be marked as a scanout. */
  680.         if (unlikely(!surface->scanout))
  681.                 return -EINVAL;
  682.  
  683.         if (unlikely(surface->mip_levels[0] != 1 ||
  684.                      surface->num_sizes != 1 ||
  685.                      surface->base_size.width < mode_cmd->width ||
  686.                      surface->base_size.height < mode_cmd->height ||
  687.                      surface->base_size.depth != 1)) {
  688.                 DRM_ERROR("Incompatible surface dimensions "
  689.                           "for requested mode.\n");
  690.                 return -EINVAL;
  691.         }
  692.  
  693.         switch (mode_cmd->depth) {
  694.         case 32:
  695.                 format = SVGA3D_A8R8G8B8;
  696.                 break;
  697.         case 24:
  698.                 format = SVGA3D_X8R8G8B8;
  699.                 break;
  700.         case 16:
  701.                 format = SVGA3D_R5G6B5;
  702.                 break;
  703.         case 15:
  704.                 format = SVGA3D_A1R5G5B5;
  705.                 break;
  706.         case 8:
  707.                 format = SVGA3D_LUMINANCE8;
  708.                 break;
  709.         default:
  710.                 DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth);
  711.                 return -EINVAL;
  712.         }
  713.  
  714.         if (unlikely(format != surface->format)) {
  715.                 DRM_ERROR("Invalid surface format for requested mode.\n");
  716.                 return -EINVAL;
  717.         }
  718.  
  719.         vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
  720.         if (!vfbs) {
  721.                 ret = -ENOMEM;
  722.                 goto out_err1;
  723.         }
  724.  
  725.         if (!vmw_surface_reference(surface)) {
  726.                 DRM_ERROR("failed to reference surface %p\n", surface);
  727.                 ret = -EINVAL;
  728.                 goto out_err2;
  729.         }
  730.  
  731.         /* XXX get the first 3 from the surface info */
  732.         vfbs->base.base.bits_per_pixel = mode_cmd->bpp;
  733.         vfbs->base.base.pitches[0] = mode_cmd->pitch;
  734.         vfbs->base.base.depth = mode_cmd->depth;
  735.         vfbs->base.base.width = mode_cmd->width;
  736.         vfbs->base.base.height = mode_cmd->height;
  737.         vfbs->surface = surface;
  738.         vfbs->base.user_handle = mode_cmd->handle;
  739. //   vfbs->master = drm_master_get(file_priv->master);
  740.  
  741.         mutex_lock(&vmaster->fb_surf_mutex);
  742.         list_add_tail(&vfbs->head, &vmaster->fb_surf);
  743.         mutex_unlock(&vmaster->fb_surf_mutex);
  744.  
  745.         *out = &vfbs->base;
  746.  
  747.         ret = drm_framebuffer_init(dev, &vfbs->base.base,
  748.                                    &vmw_framebuffer_surface_funcs);
  749.         if (ret)
  750.                 goto out_err3;
  751.  
  752.         return 0;
  753.  
  754. out_err3:
  755.         vmw_surface_unreference(&surface);
  756. out_err2:
  757.         kfree(vfbs);
  758. out_err1:
  759.         return ret;
  760. }
  761.  
  762. /*
  763.  * Dmabuf framebuffer code
  764.  */
  765.  
  766. #define vmw_framebuffer_to_vfbd(x) \
  767.         container_of(x, struct vmw_framebuffer_dmabuf, base.base)
  768.  
  769. struct vmw_framebuffer_dmabuf {
  770.         struct vmw_framebuffer base;
  771.         struct vmw_dma_buffer *buffer;
  772. };
  773.  
  774. static void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer)
  775. {
  776.         struct vmw_framebuffer_dmabuf *vfbd =
  777.                 vmw_framebuffer_to_vfbd(framebuffer);
  778.  
  779. //   drm_framebuffer_cleanup(framebuffer);
  780. //   vmw_dmabuf_unreference(&vfbd->buffer);
  781. //   ttm_base_object_unref(&vfbd->base.user_obj);
  782.  
  783.         kfree(vfbd);
  784. }
  785.  
  786. static int do_dmabuf_dirty_ldu(struct vmw_private *dev_priv,
  787.                                struct vmw_framebuffer *framebuffer,
  788.                                unsigned flags, unsigned color,
  789.                                struct drm_clip_rect *clips,
  790.                                unsigned num_clips, int increment)
  791. {
  792.         size_t fifo_size;
  793.         int i;
  794.  
  795.         struct {
  796.                 uint32_t header;
  797.                 SVGAFifoCmdUpdate body;
  798.         } *cmd;
  799.  
  800.         fifo_size = sizeof(*cmd) * num_clips;
  801.         cmd = vmw_fifo_reserve(dev_priv, fifo_size);
  802.         if (unlikely(cmd == NULL)) {
  803.                 DRM_ERROR("Fifo reserve failed.\n");
  804.                 return -ENOMEM;
  805.         }
  806.  
  807.         memset(cmd, 0, fifo_size);
  808.         for (i = 0; i < num_clips; i++, clips += increment) {
  809.                 cmd[i].header = cpu_to_le32(SVGA_CMD_UPDATE);
  810.                 cmd[i].body.x = cpu_to_le32(clips->x1);
  811.                 cmd[i].body.y = cpu_to_le32(clips->y1);
  812.                 cmd[i].body.width = cpu_to_le32(clips->x2 - clips->x1);
  813.                 cmd[i].body.height = cpu_to_le32(clips->y2 - clips->y1);
  814.         }
  815.  
  816.         vmw_fifo_commit(dev_priv, fifo_size);
  817.         return 0;
  818. }
  819.  
  820. static int do_dmabuf_define_gmrfb(struct drm_file *file_priv,
  821.                                   struct vmw_private *dev_priv,
  822.                                   struct vmw_framebuffer *framebuffer)
  823. {
  824.         int depth = framebuffer->base.depth;
  825.         size_t fifo_size;
  826.         int ret;
  827.  
  828.         struct {
  829.                 uint32_t header;
  830.                 SVGAFifoCmdDefineGMRFB body;
  831.         } *cmd;
  832.  
  833.         /* Emulate RGBA support, contrary to svga_reg.h this is not
  834.          * supported by hosts. This is only a problem if we are reading
  835.          * this value later and expecting what we uploaded back.
  836.          */
  837.         if (depth == 32)
  838.                 depth = 24;
  839.  
  840.         fifo_size = sizeof(*cmd);
  841.         cmd = kmalloc(fifo_size, GFP_KERNEL);
  842.         if (unlikely(cmd == NULL)) {
  843.                 DRM_ERROR("Failed to allocate temporary cmd buffer.\n");
  844.                 return -ENOMEM;
  845.         }
  846.  
  847.         memset(cmd, 0, fifo_size);
  848.         cmd->header = SVGA_CMD_DEFINE_GMRFB;
  849.         cmd->body.format.bitsPerPixel = framebuffer->base.bits_per_pixel;
  850.         cmd->body.format.colorDepth = depth;
  851.         cmd->body.format.reserved = 0;
  852.         cmd->body.bytesPerLine = framebuffer->base.pitches[0];
  853.         cmd->body.ptr.gmrId = framebuffer->user_handle;
  854.         cmd->body.ptr.offset = 0;
  855.  
  856.         ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
  857.                                   fifo_size, 0, NULL, NULL);
  858.  
  859.         kfree(cmd);
  860.  
  861.         return ret;
  862. }
  863.  
  864. static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
  865.                                struct vmw_private *dev_priv,
  866.                                struct vmw_framebuffer *framebuffer,
  867.                                unsigned flags, unsigned color,
  868.                                struct drm_clip_rect *clips,
  869.                                unsigned num_clips, int increment,
  870.                                struct vmw_fence_obj **out_fence)
  871. {
  872.         struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
  873.         struct drm_clip_rect *clips_ptr;
  874.         int i, k, num_units, ret;
  875.         struct drm_crtc *crtc;
  876.         size_t fifo_size;
  877.  
  878.         struct {
  879.                 uint32_t header;
  880.                 SVGAFifoCmdBlitGMRFBToScreen body;
  881.         } *blits;
  882.  
  883.         ret = do_dmabuf_define_gmrfb(file_priv, dev_priv, framebuffer);
  884.         if (unlikely(ret != 0))
  885.                 return ret; /* define_gmrfb prints warnings */
  886.  
  887.         fifo_size = sizeof(*blits) * num_clips;
  888.         blits = kmalloc(fifo_size, GFP_KERNEL);
  889.         if (unlikely(blits == NULL)) {
  890.                 DRM_ERROR("Failed to allocate temporary cmd buffer.\n");
  891.                 return -ENOMEM;
  892.         }
  893.  
  894.         num_units = 0;
  895.         list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
  896.                 if (crtc->fb != &framebuffer->base)
  897.                         continue;
  898.                 units[num_units++] = vmw_crtc_to_du(crtc);
  899.         }
  900.  
  901.         for (k = 0; k < num_units; k++) {
  902.                 struct vmw_display_unit *unit = units[k];
  903.                 int hit_num = 0;
  904.  
  905.                 clips_ptr = clips;
  906.                 for (i = 0; i < num_clips; i++, clips_ptr += increment) {
  907.                         int clip_x1 = clips_ptr->x1 - unit->crtc.x;
  908.                         int clip_y1 = clips_ptr->y1 - unit->crtc.y;
  909.                         int clip_x2 = clips_ptr->x2 - unit->crtc.x;
  910.                         int clip_y2 = clips_ptr->y2 - unit->crtc.y;
  911.                         int move_x, move_y;
  912.  
  913.                         /* skip any crtcs that misses the clip region */
  914.                         if (clip_x1 >= unit->crtc.mode.hdisplay ||
  915.                             clip_y1 >= unit->crtc.mode.vdisplay ||
  916.                             clip_x2 <= 0 || clip_y2 <= 0)
  917.                                 continue;
  918.  
  919.                         /* clip size to crtc size */
  920.                         clip_x2 = min_t(int, clip_x2, unit->crtc.mode.hdisplay);
  921.                         clip_y2 = min_t(int, clip_y2, unit->crtc.mode.vdisplay);
  922.  
  923.                         /* translate both src and dest to bring clip into screen */
  924.                         move_x = min_t(int, clip_x1, 0);
  925.                         move_y = min_t(int, clip_y1, 0);
  926.  
  927.                         /* actual translate done here */
  928.                         blits[hit_num].header = SVGA_CMD_BLIT_GMRFB_TO_SCREEN;
  929.                         blits[hit_num].body.destScreenId = unit->unit;
  930.                         blits[hit_num].body.srcOrigin.x = clips_ptr->x1 - move_x;
  931.                         blits[hit_num].body.srcOrigin.y = clips_ptr->y1 - move_y;
  932.                         blits[hit_num].body.destRect.left = clip_x1 - move_x;
  933.                         blits[hit_num].body.destRect.top = clip_y1 - move_y;
  934.                         blits[hit_num].body.destRect.right = clip_x2;
  935.                         blits[hit_num].body.destRect.bottom = clip_y2;
  936.                         hit_num++;
  937.                 }
  938.  
  939.                 /* no clips hit the crtc */
  940.                 if (hit_num == 0)
  941.                         continue;
  942.  
  943.                 /* only return the last fence */
  944.                 if (out_fence && *out_fence)
  945.                         vmw_fence_obj_unreference(out_fence);
  946.  
  947.                 fifo_size = sizeof(*blits) * hit_num;
  948.                 ret = vmw_execbuf_process(file_priv, dev_priv, NULL, blits,
  949.                                           fifo_size, 0, NULL, out_fence);
  950.  
  951.                 if (unlikely(ret != 0))
  952.                         break;
  953.         }
  954.  
  955.         kfree(blits);
  956.  
  957.         return ret;
  958. }
  959.  
  960. static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
  961.                                  struct drm_file *file_priv,
  962.                                  unsigned flags, unsigned color,
  963.                                  struct drm_clip_rect *clips,
  964.                                  unsigned num_clips)
  965. {
  966.         struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
  967.         struct vmw_master *vmaster = vmw_master(file_priv->master);
  968.         struct vmw_framebuffer_dmabuf *vfbd =
  969.                 vmw_framebuffer_to_vfbd(framebuffer);
  970.         struct drm_clip_rect norect;
  971.         int ret, increment = 1;
  972.  
  973.         drm_modeset_lock_all(dev_priv->dev);
  974.  
  975.         ret = ttm_read_lock(&vmaster->lock, true);
  976.         if (unlikely(ret != 0)) {
  977.                 drm_modeset_unlock_all(dev_priv->dev);
  978.                 return ret;
  979.         }
  980.  
  981.         if (!num_clips) {
  982.                 num_clips = 1;
  983.                 clips = &norect;
  984.                 norect.x1 = norect.y1 = 0;
  985.                 norect.x2 = framebuffer->width;
  986.                 norect.y2 = framebuffer->height;
  987.         } else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
  988.                 num_clips /= 2;
  989.                 increment = 2;
  990.         }
  991.  
  992.         if (dev_priv->ldu_priv) {
  993.                 ret = do_dmabuf_dirty_ldu(dev_priv, &vfbd->base,
  994.                                           flags, color,
  995.                                           clips, num_clips, increment);
  996.         } else {
  997.                 ret = do_dmabuf_dirty_sou(file_priv, dev_priv, &vfbd->base,
  998.                                           flags, color,
  999.                                           clips, num_clips, increment, NULL);
  1000.         }
  1001.  
  1002.         ttm_read_unlock(&vmaster->lock);
  1003.  
  1004.         drm_modeset_unlock_all(dev_priv->dev);
  1005.  
  1006.         return ret;
  1007. }
  1008.  
  1009. static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = {
  1010.         .destroy = vmw_framebuffer_dmabuf_destroy,
  1011.         .dirty = vmw_framebuffer_dmabuf_dirty,
  1012. };
  1013.  
  1014. /**
  1015.  * Pin the dmabuffer to the start of vram.
  1016.  */
  1017. static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb)
  1018. {
  1019.         struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
  1020.         struct vmw_framebuffer_dmabuf *vfbd =
  1021.                 vmw_framebuffer_to_vfbd(&vfb->base);
  1022.         int ret;
  1023.  
  1024.         /* This code should not be used with screen objects */
  1025.         BUG_ON(dev_priv->sou_priv);
  1026.  
  1027. //   vmw_overlay_pause_all(dev_priv);
  1028.  
  1029.         ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer, true, false);
  1030.  
  1031. //   vmw_overlay_resume_all(dev_priv);
  1032.  
  1033.         WARN_ON(ret != 0);
  1034.  
  1035.         return 0;
  1036. }
  1037.  
  1038. static int vmw_framebuffer_dmabuf_unpin(struct vmw_framebuffer *vfb)
  1039. {
  1040.         struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
  1041.         struct vmw_framebuffer_dmabuf *vfbd =
  1042.                 vmw_framebuffer_to_vfbd(&vfb->base);
  1043.  
  1044.         if (!vfbd->buffer) {
  1045.                 WARN_ON(!vfbd->buffer);
  1046.                 return 0;
  1047.         }
  1048.  
  1049.         return vmw_dmabuf_unpin(dev_priv, vfbd->buffer, false);
  1050. }
  1051.  
  1052. #if 0
  1053. static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
  1054.                                           struct vmw_dma_buffer *dmabuf,
  1055.                                           struct vmw_framebuffer **out,
  1056.                                           const struct drm_mode_fb_cmd
  1057.                                           *mode_cmd)
  1058.  
  1059. {
  1060.         struct drm_device *dev = dev_priv->dev;
  1061.         struct vmw_framebuffer_dmabuf *vfbd;
  1062.         unsigned int requested_size;
  1063.         int ret;
  1064.  
  1065.         requested_size = mode_cmd->height * mode_cmd->pitch;
  1066.         if (unlikely(requested_size > dmabuf->base.num_pages * PAGE_SIZE)) {
  1067.                 DRM_ERROR("Screen buffer object size is too small "
  1068.                           "for requested mode.\n");
  1069.                 return -EINVAL;
  1070.         }
  1071.  
  1072.         /* Limited framebuffer color depth support for screen objects */
  1073.         if (dev_priv->sou_priv) {
  1074.                 switch (mode_cmd->depth) {
  1075.                 case 32:
  1076.                 case 24:
  1077.                         /* Only support 32 bpp for 32 and 24 depth fbs */
  1078.                         if (mode_cmd->bpp == 32)
  1079.                                 break;
  1080.  
  1081.                         DRM_ERROR("Invalid color depth/bbp: %d %d\n",
  1082.                                   mode_cmd->depth, mode_cmd->bpp);
  1083.                         return -EINVAL;
  1084.                 case 16:
  1085.                 case 15:
  1086.                         /* Only support 16 bpp for 16 and 15 depth fbs */
  1087.                         if (mode_cmd->bpp == 16)
  1088.                                 break;
  1089.  
  1090.                         DRM_ERROR("Invalid color depth/bbp: %d %d\n",
  1091.                                   mode_cmd->depth, mode_cmd->bpp);
  1092.                         return -EINVAL;
  1093.                 default:
  1094.                         DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth);
  1095.                         return -EINVAL;
  1096.                 }
  1097.         }
  1098.  
  1099.         vfbd = kzalloc(sizeof(*vfbd), GFP_KERNEL);
  1100.         if (!vfbd) {
  1101.                 ret = -ENOMEM;
  1102.                 goto out_err1;
  1103.         }
  1104.  
  1105.         if (!vmw_dmabuf_reference(dmabuf)) {
  1106.                 DRM_ERROR("failed to reference dmabuf %p\n", dmabuf);
  1107.                 ret = -EINVAL;
  1108.                 goto out_err2;
  1109.         }
  1110.  
  1111.         vfbd->base.base.bits_per_pixel = mode_cmd->bpp;
  1112.         vfbd->base.base.pitches[0] = mode_cmd->pitch;
  1113.         vfbd->base.base.depth = mode_cmd->depth;
  1114.         vfbd->base.base.width = mode_cmd->width;
  1115.         vfbd->base.base.height = mode_cmd->height;
  1116.         if (!dev_priv->sou_priv) {
  1117.                 vfbd->base.pin = vmw_framebuffer_dmabuf_pin;
  1118.                 vfbd->base.unpin = vmw_framebuffer_dmabuf_unpin;
  1119.         }
  1120.         vfbd->base.dmabuf = true;
  1121.         vfbd->buffer = dmabuf;
  1122.         vfbd->base.user_handle = mode_cmd->handle;
  1123.         *out = &vfbd->base;
  1124.  
  1125.         ret = drm_framebuffer_init(dev, &vfbd->base.base,
  1126.                                    &vmw_framebuffer_dmabuf_funcs);
  1127.         if (ret)
  1128.                 goto out_err3;
  1129.  
  1130.         return 0;
  1131.  
  1132. out_err3:
  1133.         vmw_dmabuf_unreference(&dmabuf);
  1134. out_err2:
  1135.         kfree(vfbd);
  1136. out_err1:
  1137.         return ret;
  1138. }
  1139. #endif
  1140.  
  1141. /*
  1142.  * Generic Kernel modesetting functions
  1143.  */
  1144.  
  1145. static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
  1146.                                                  struct drm_file *file_priv,
  1147.                                                  struct drm_mode_fb_cmd2 *mode_cmd2)
  1148. {
  1149.         struct vmw_private *dev_priv = vmw_priv(dev);
  1150.         struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
  1151.         struct vmw_framebuffer *vfb = NULL;
  1152.         struct vmw_surface *surface = NULL;
  1153.         struct vmw_dma_buffer *bo = NULL;
  1154.         struct ttm_base_object *user_obj;
  1155.         struct drm_mode_fb_cmd mode_cmd;
  1156.         int ret;
  1157.  
  1158.         mode_cmd.width = mode_cmd2->width;
  1159.         mode_cmd.height = mode_cmd2->height;
  1160.         mode_cmd.pitch = mode_cmd2->pitches[0];
  1161.         mode_cmd.handle = mode_cmd2->handles[0];
  1162.         drm_fb_get_bpp_depth(mode_cmd2->pixel_format, &mode_cmd.depth,
  1163.                                     &mode_cmd.bpp);
  1164.  
  1165.         /**
  1166.          * This code should be conditioned on Screen Objects not being used.
  1167.          * If screen objects are used, we can allocate a GMR to hold the
  1168.          * requested framebuffer.
  1169.          */
  1170.  
  1171.         if (!vmw_kms_validate_mode_vram(dev_priv,
  1172.                                         mode_cmd.pitch,
  1173.                                         mode_cmd.height)) {
  1174.                 DRM_ERROR("VRAM size is too small for requested mode.\n");
  1175.                 return ERR_PTR(-ENOMEM);
  1176.         }
  1177.  
  1178.         /*
  1179.          * Take a reference on the user object of the resource
  1180.          * backing the kms fb. This ensures that user-space handle
  1181.          * lookups on that resource will always work as long as
  1182.          * it's registered with a kms framebuffer. This is important,
  1183.          * since vmw_execbuf_process identifies resources in the
  1184.          * command stream using user-space handles.
  1185.          */
  1186.  
  1187.         user_obj = ttm_base_object_lookup(tfile, mode_cmd.handle);
  1188.         if (unlikely(user_obj == NULL)) {
  1189.                 DRM_ERROR("Could not locate requested kms frame buffer.\n");
  1190.                 return ERR_PTR(-ENOENT);
  1191.         }
  1192.  
  1193.         /**
  1194.          * End conditioned code.
  1195.          */
  1196.  
  1197.         /* returns either a dmabuf or surface */
  1198. //   ret = vmw_user_lookup_handle(dev_priv, tfile,
  1199. //                    mode_cmd.handle,
  1200. //                    &surface, &bo);
  1201. //   if (ret)
  1202. //       goto err_out;
  1203.  
  1204.         /* Create the new framebuffer depending one what we got back */
  1205. //   if (bo)
  1206. //       ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb,
  1207. //                            &mode_cmd);
  1208. //   else if (surface)
  1209.                 ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv,
  1210.                                                       surface, &vfb, &mode_cmd);
  1211. //   else
  1212. //       BUG();
  1213.  
  1214. err_out:
  1215.         /* vmw_user_lookup_handle takes one ref so does new_fb */
  1216. //   if (bo)
  1217. //       vmw_dmabuf_unreference(&bo);
  1218. //   if (surface)
  1219. //       vmw_surface_unreference(&surface);
  1220.  
  1221.         if (ret) {
  1222.                 DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
  1223. //       ttm_base_object_unref(&user_obj);
  1224.                 return ERR_PTR(ret);
  1225.         } else
  1226.                 vfb->user_obj = user_obj;
  1227.  
  1228.         return &vfb->base;
  1229. }
  1230.  
  1231. static const struct drm_mode_config_funcs vmw_kms_funcs = {
  1232.         .fb_create = vmw_kms_fb_create,
  1233. };
  1234.  
  1235. int vmw_kms_present(struct vmw_private *dev_priv,
  1236.                     struct drm_file *file_priv,
  1237.                     struct vmw_framebuffer *vfb,
  1238.                     struct vmw_surface *surface,
  1239.                     uint32_t sid,
  1240.                     int32_t destX, int32_t destY,
  1241.                     struct drm_vmw_rect *clips,
  1242.                     uint32_t num_clips)
  1243. {
  1244.         struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
  1245.         struct drm_clip_rect *tmp;
  1246.         struct drm_crtc *crtc;
  1247.         size_t fifo_size;
  1248.         int i, k, num_units;
  1249.         int ret = 0; /* silence warning */
  1250.         int left, right, top, bottom;
  1251.  
  1252.         struct {
  1253.                 SVGA3dCmdHeader header;
  1254.                 SVGA3dCmdBlitSurfaceToScreen body;
  1255.         } *cmd;
  1256.         SVGASignedRect *blits;
  1257.  
  1258.         num_units = 0;
  1259.         list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
  1260.                 if (crtc->fb != &vfb->base)
  1261.                         continue;
  1262.                 units[num_units++] = vmw_crtc_to_du(crtc);
  1263.         }
  1264.  
  1265.         BUG_ON(surface == NULL);
  1266.         BUG_ON(!clips || !num_clips);
  1267.  
  1268.         tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL);
  1269.         if (unlikely(tmp == NULL)) {
  1270.                 DRM_ERROR("Temporary cliprect memory alloc failed.\n");
  1271.                 return -ENOMEM;
  1272.         }
  1273.  
  1274.         fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips;
  1275.         cmd = kmalloc(fifo_size, GFP_KERNEL);
  1276.         if (unlikely(cmd == NULL)) {
  1277.                 DRM_ERROR("Failed to allocate temporary fifo memory.\n");
  1278.                 ret = -ENOMEM;
  1279.                 goto out_free_tmp;
  1280.         }
  1281.  
  1282.         left = clips->x;
  1283.         right = clips->x + clips->w;
  1284.         top = clips->y;
  1285.         bottom = clips->y + clips->h;
  1286.  
  1287.         for (i = 1; i < num_clips; i++) {
  1288.                 left = min_t(int, left, (int)clips[i].x);
  1289.                 right = max_t(int, right, (int)clips[i].x + clips[i].w);
  1290.                 top = min_t(int, top, (int)clips[i].y);
  1291.                 bottom = max_t(int, bottom, (int)clips[i].y + clips[i].h);
  1292.         }
  1293.  
  1294.         /* only need to do this once */
  1295.         memset(cmd, 0, fifo_size);
  1296.         cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
  1297.  
  1298.         blits = (SVGASignedRect *)&cmd[1];
  1299.  
  1300.         cmd->body.srcRect.left = left;
  1301.         cmd->body.srcRect.right = right;
  1302.         cmd->body.srcRect.top = top;
  1303.         cmd->body.srcRect.bottom = bottom;
  1304.  
  1305.         for (i = 0; i < num_clips; i++) {
  1306.                 tmp[i].x1 = clips[i].x - left;
  1307.                 tmp[i].x2 = clips[i].x + clips[i].w - left;
  1308.                 tmp[i].y1 = clips[i].y - top;
  1309.                 tmp[i].y2 = clips[i].y + clips[i].h - top;
  1310.         }
  1311.  
  1312.         for (k = 0; k < num_units; k++) {
  1313.                 struct vmw_display_unit *unit = units[k];
  1314.                 struct vmw_clip_rect clip;
  1315.                 int num;
  1316.  
  1317.                 clip.x1 = left + destX - unit->crtc.x;
  1318.                 clip.y1 = top + destY - unit->crtc.y;
  1319.                 clip.x2 = right + destX - unit->crtc.x;
  1320.                 clip.y2 = bottom + destY - unit->crtc.y;
  1321.  
  1322.                 /* skip any crtcs that misses the clip region */
  1323.                 if (clip.x1 >= unit->crtc.mode.hdisplay ||
  1324.                     clip.y1 >= unit->crtc.mode.vdisplay ||
  1325.                     clip.x2 <= 0 || clip.y2 <= 0)
  1326.                         continue;
  1327.  
  1328.                 /*
  1329.                  * In order for the clip rects to be correctly scaled
  1330.                  * the src and dest rects needs to be the same size.
  1331.                  */
  1332.                 cmd->body.destRect.left = clip.x1;
  1333.                 cmd->body.destRect.right = clip.x2;
  1334.                 cmd->body.destRect.top = clip.y1;
  1335.                 cmd->body.destRect.bottom = clip.y2;
  1336.  
  1337.                 /* create a clip rect of the crtc in dest coords */
  1338.                 clip.x2 = unit->crtc.mode.hdisplay - clip.x1;
  1339.                 clip.y2 = unit->crtc.mode.vdisplay - clip.y1;
  1340.                 clip.x1 = 0 - clip.x1;
  1341.                 clip.y1 = 0 - clip.y1;
  1342.  
  1343.                 /* need to reset sid as it is changed by execbuf */
  1344.                 cmd->body.srcImage.sid = sid;
  1345.                 cmd->body.destScreenId = unit->unit;
  1346.  
  1347.                 /* clip and write blits to cmd stream */
  1348.                 vmw_clip_cliprects(tmp, num_clips, clip, blits, &num);
  1349.  
  1350.                 /* if no cliprects hit skip this */
  1351.                 if (num == 0)
  1352.                         continue;
  1353.  
  1354.                 /* recalculate package length */
  1355.                 fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
  1356.                 cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
  1357.                 ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
  1358.                                           fifo_size, 0, NULL, NULL);
  1359.  
  1360.                 if (unlikely(ret != 0))
  1361.                         break;
  1362.         }
  1363.  
  1364.         kfree(cmd);
  1365. out_free_tmp:
  1366.         kfree(tmp);
  1367.  
  1368.         return ret;
  1369. }
  1370.  
  1371. int vmw_kms_readback(struct vmw_private *dev_priv,
  1372.                      struct drm_file *file_priv,
  1373.                      struct vmw_framebuffer *vfb,
  1374.                      struct drm_vmw_fence_rep __user *user_fence_rep,
  1375.                      struct drm_vmw_rect *clips,
  1376.                      uint32_t num_clips)
  1377. {
  1378.         struct vmw_framebuffer_dmabuf *vfbd =
  1379.                 vmw_framebuffer_to_vfbd(&vfb->base);
  1380.         struct vmw_dma_buffer *dmabuf = vfbd->buffer;
  1381.         struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
  1382.         struct drm_crtc *crtc;
  1383.         size_t fifo_size;
  1384.         int i, k, ret, num_units, blits_pos;
  1385.  
  1386.         struct {
  1387.                 uint32_t header;
  1388.                 SVGAFifoCmdDefineGMRFB body;
  1389.         } *cmd;
  1390.         struct {
  1391.                 uint32_t header;
  1392.                 SVGAFifoCmdBlitScreenToGMRFB body;
  1393.         } *blits;
  1394.  
  1395.         num_units = 0;
  1396.         list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
  1397.                 if (crtc->fb != &vfb->base)
  1398.                         continue;
  1399.                 units[num_units++] = vmw_crtc_to_du(crtc);
  1400.         }
  1401.  
  1402.         BUG_ON(dmabuf == NULL);
  1403.         BUG_ON(!clips || !num_clips);
  1404.  
  1405.         /* take a safe guess at fifo size */
  1406.         fifo_size = sizeof(*cmd) + sizeof(*blits) * num_clips * num_units;
  1407.         cmd = kmalloc(fifo_size, GFP_KERNEL);
  1408.         if (unlikely(cmd == NULL)) {
  1409.                 DRM_ERROR("Failed to allocate temporary fifo memory.\n");
  1410.                 return -ENOMEM;
  1411.         }
  1412.  
  1413.         memset(cmd, 0, fifo_size);
  1414.         cmd->header = SVGA_CMD_DEFINE_GMRFB;
  1415.         cmd->body.format.bitsPerPixel = vfb->base.bits_per_pixel;
  1416.         cmd->body.format.colorDepth = vfb->base.depth;
  1417.         cmd->body.format.reserved = 0;
  1418.         cmd->body.bytesPerLine = vfb->base.pitches[0];
  1419.         cmd->body.ptr.gmrId = vfb->user_handle;
  1420.         cmd->body.ptr.offset = 0;
  1421.  
  1422.         blits = (void *)&cmd[1];
  1423.         blits_pos = 0;
  1424.         for (i = 0; i < num_units; i++) {
  1425.                 struct drm_vmw_rect *c = clips;
  1426.                 for (k = 0; k < num_clips; k++, c++) {
  1427.                         /* transform clip coords to crtc origin based coords */
  1428.                         int clip_x1 = c->x - units[i]->crtc.x;
  1429.                         int clip_x2 = c->x - units[i]->crtc.x + c->w;
  1430.                         int clip_y1 = c->y - units[i]->crtc.y;
  1431.                         int clip_y2 = c->y - units[i]->crtc.y + c->h;
  1432.                         int dest_x = c->x;
  1433.                         int dest_y = c->y;
  1434.  
  1435.                         /* compensate for clipping, we negate
  1436.                          * a negative number and add that.
  1437.                          */
  1438.                         if (clip_x1 < 0)
  1439.                                 dest_x += -clip_x1;
  1440.                         if (clip_y1 < 0)
  1441.                                 dest_y += -clip_y1;
  1442.  
  1443.                         /* clip */
  1444.                         clip_x1 = max(clip_x1, 0);
  1445.                         clip_y1 = max(clip_y1, 0);
  1446.                         clip_x2 = min(clip_x2, units[i]->crtc.mode.hdisplay);
  1447.                         clip_y2 = min(clip_y2, units[i]->crtc.mode.vdisplay);
  1448.  
  1449.                         /* and cull any rects that misses the crtc */
  1450.                         if (clip_x1 >= units[i]->crtc.mode.hdisplay ||
  1451.                             clip_y1 >= units[i]->crtc.mode.vdisplay ||
  1452.                             clip_x2 <= 0 || clip_y2 <= 0)
  1453.                                 continue;
  1454.  
  1455.                         blits[blits_pos].header = SVGA_CMD_BLIT_SCREEN_TO_GMRFB;
  1456.                         blits[blits_pos].body.srcScreenId = units[i]->unit;
  1457.                         blits[blits_pos].body.destOrigin.x = dest_x;
  1458.                         blits[blits_pos].body.destOrigin.y = dest_y;
  1459.  
  1460.                         blits[blits_pos].body.srcRect.left = clip_x1;
  1461.                         blits[blits_pos].body.srcRect.top = clip_y1;
  1462.                         blits[blits_pos].body.srcRect.right = clip_x2;
  1463.                         blits[blits_pos].body.srcRect.bottom = clip_y2;
  1464.                         blits_pos++;
  1465.                 }
  1466.         }
  1467.         /* reset size here and use calculated exact size from loops */
  1468.         fifo_size = sizeof(*cmd) + sizeof(*blits) * blits_pos;
  1469.  
  1470.         ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size,
  1471.                                   0, user_fence_rep, NULL);
  1472.  
  1473.         kfree(cmd);
  1474.  
  1475.         return ret;
  1476. }
  1477.  
  1478. int vmw_kms_init(struct vmw_private *dev_priv)
  1479. {
  1480.         struct drm_device *dev = dev_priv->dev;
  1481.         int ret;
  1482.  
  1483.     ENTER();
  1484.  
  1485.         drm_mode_config_init(dev);
  1486.         dev->mode_config.funcs = &vmw_kms_funcs;
  1487.         dev->mode_config.min_width = 1;
  1488.         dev->mode_config.min_height = 1;
  1489.         /* assumed largest fb size */
  1490.         dev->mode_config.max_width = 8192;
  1491.         dev->mode_config.max_height = 8192;
  1492.  
  1493.         ret = vmw_kms_init_screen_object_display(dev_priv);
  1494. //    if (ret) /* Fallback */
  1495. //       (void)vmw_kms_init_legacy_display_system(dev_priv);
  1496.  
  1497.     LEAVE();
  1498.  
  1499.         return 0;
  1500. }
  1501.  
  1502. int vmw_kms_close(struct vmw_private *dev_priv)
  1503. {
  1504.         /*
  1505.          * Docs says we should take the lock before calling this function
  1506.          * but since it destroys encoders and our destructor calls
  1507.          * drm_encoder_cleanup which takes the lock we deadlock.
  1508.          */
  1509. //   drm_mode_config_cleanup(dev_priv->dev);
  1510. //   if (dev_priv->sou_priv)
  1511. //       vmw_kms_close_screen_object_display(dev_priv);
  1512. //   else
  1513. //       vmw_kms_close_legacy_display_system(dev_priv);
  1514.         return 0;
  1515. }
  1516.  
  1517. #if 0
  1518. int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
  1519.                                 struct drm_file *file_priv)
  1520. {
  1521.         struct drm_vmw_cursor_bypass_arg *arg = data;
  1522.         struct vmw_display_unit *du;
  1523.         struct drm_mode_object *obj;
  1524.         struct drm_crtc *crtc;
  1525.         int ret = 0;
  1526.  
  1527.  
  1528.         mutex_lock(&dev->mode_config.mutex);
  1529.         if (arg->flags & DRM_VMW_CURSOR_BYPASS_ALL) {
  1530.  
  1531.                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
  1532.                         du = vmw_crtc_to_du(crtc);
  1533.                         du->hotspot_x = arg->xhot;
  1534.                         du->hotspot_y = arg->yhot;
  1535.                 }
  1536.  
  1537.                 mutex_unlock(&dev->mode_config.mutex);
  1538.                 return 0;
  1539.         }
  1540.  
  1541.         obj = drm_mode_object_find(dev, arg->crtc_id, DRM_MODE_OBJECT_CRTC);
  1542.         if (!obj) {
  1543.                 ret = -ENOENT;
  1544.                 goto out;
  1545.         }
  1546.  
  1547.         crtc = obj_to_crtc(obj);
  1548.         du = vmw_crtc_to_du(crtc);
  1549.  
  1550.         du->hotspot_x = arg->xhot;
  1551.         du->hotspot_y = arg->yhot;
  1552.  
  1553. out:
  1554.         mutex_unlock(&dev->mode_config.mutex);
  1555.  
  1556.         return ret;
  1557. }
  1558. #endif
  1559.  
  1560. int vmw_kms_write_svga(struct vmw_private *vmw_priv,
  1561.                         unsigned width, unsigned height, unsigned pitch,
  1562.                         unsigned bpp, unsigned depth)
  1563. {
  1564.         if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
  1565.                 vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch);
  1566.         else if (vmw_fifo_have_pitchlock(vmw_priv))
  1567.                 iowrite32(pitch, vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
  1568.         vmw_write(vmw_priv, SVGA_REG_WIDTH, width);
  1569.         vmw_write(vmw_priv, SVGA_REG_HEIGHT, height);
  1570.         vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bpp);
  1571.  
  1572.         if (vmw_read(vmw_priv, SVGA_REG_DEPTH) != depth) {
  1573.                 DRM_ERROR("Invalid depth %u for %u bpp, host expects %u\n",
  1574.                           depth, bpp, vmw_read(vmw_priv, SVGA_REG_DEPTH));
  1575.                 return -EINVAL;
  1576.         }
  1577.  
  1578.         return 0;
  1579. }
  1580.  
  1581. int vmw_kms_save_vga(struct vmw_private *vmw_priv)
  1582. {
  1583.         struct vmw_vga_topology_state *save;
  1584.         uint32_t i;
  1585.  
  1586.         vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH);
  1587.         vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT);
  1588.         vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
  1589.         if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
  1590.                 vmw_priv->vga_pitchlock =
  1591.                   vmw_read(vmw_priv, SVGA_REG_PITCHLOCK);
  1592.         else if (vmw_fifo_have_pitchlock(vmw_priv))
  1593.                 vmw_priv->vga_pitchlock = ioread32(vmw_priv->mmio_virt +
  1594.                                                        SVGA_FIFO_PITCHLOCK);
  1595.  
  1596.         if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
  1597.                 return 0;
  1598.  
  1599.         vmw_priv->num_displays = vmw_read(vmw_priv,
  1600.                                           SVGA_REG_NUM_GUEST_DISPLAYS);
  1601.  
  1602.         if (vmw_priv->num_displays == 0)
  1603.                 vmw_priv->num_displays = 1;
  1604.  
  1605.         for (i = 0; i < vmw_priv->num_displays; ++i) {
  1606.                 save = &vmw_priv->vga_save[i];
  1607.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
  1608.                 save->primary = vmw_read(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY);
  1609.                 save->pos_x = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_X);
  1610.                 save->pos_y = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y);
  1611.                 save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
  1612.                 save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
  1613.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
  1614.                 if (i == 0 && vmw_priv->num_displays == 1 &&
  1615.                     save->width == 0 && save->height == 0) {
  1616.  
  1617.                         /*
  1618.                          * It should be fairly safe to assume that these
  1619.                          * values are uninitialized.
  1620.                          */
  1621.  
  1622.                         save->width = vmw_priv->vga_width - save->pos_x;
  1623.                         save->height = vmw_priv->vga_height - save->pos_y;
  1624.                 }
  1625.         }
  1626.  
  1627.         return 0;
  1628. }
  1629.  
  1630. int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
  1631. {
  1632.         struct vmw_vga_topology_state *save;
  1633.         uint32_t i;
  1634.  
  1635.         vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width);
  1636.         vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height);
  1637.         vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
  1638.         if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
  1639.                 vmw_write(vmw_priv, SVGA_REG_PITCHLOCK,
  1640.                           vmw_priv->vga_pitchlock);
  1641.         else if (vmw_fifo_have_pitchlock(vmw_priv))
  1642.                 iowrite32(vmw_priv->vga_pitchlock,
  1643.                           vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
  1644.  
  1645.         if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
  1646.                 return 0;
  1647.  
  1648.         for (i = 0; i < vmw_priv->num_displays; ++i) {
  1649.                 save = &vmw_priv->vga_save[i];
  1650.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
  1651.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, save->primary);
  1652.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, save->pos_x);
  1653.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, save->pos_y);
  1654.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, save->width);
  1655.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, save->height);
  1656.                 vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
  1657.         }
  1658.  
  1659.         return 0;
  1660. }
  1661.  
  1662. bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
  1663.                                 uint32_t pitch,
  1664.                                 uint32_t height)
  1665. {
  1666.         return ((u64) pitch * (u64) height) < (u64) dev_priv->prim_bb_mem;
  1667. }
  1668.  
  1669.  
  1670. /**
  1671.  * Function called by DRM code called with vbl_lock held.
  1672.  */
  1673. u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc)
  1674. {
  1675.         return 0;
  1676. }
  1677.  
  1678. /**
  1679.  * Function called by DRM code called with vbl_lock held.
  1680.  */
  1681. int vmw_enable_vblank(struct drm_device *dev, int crtc)
  1682. {
  1683.         return -ENOSYS;
  1684. }
  1685.  
  1686. /**
  1687.  * Function called by DRM code called with vbl_lock held.
  1688.  */
  1689. void vmw_disable_vblank(struct drm_device *dev, int crtc)
  1690. {
  1691. }
  1692.  
  1693.  
  1694. /*
  1695.  * Small shared kms functions.
  1696.  */
  1697.  
  1698. static int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
  1699.                          struct drm_vmw_rect *rects)
  1700. {
  1701.         struct drm_device *dev = dev_priv->dev;
  1702.         struct vmw_display_unit *du;
  1703.         struct drm_connector *con;
  1704.  
  1705.         mutex_lock(&dev->mode_config.mutex);
  1706.  
  1707. #if 0
  1708.         {
  1709.                 unsigned int i;
  1710.  
  1711.                 DRM_INFO("%s: new layout ", __func__);
  1712.                 for (i = 0; i < num; i++)
  1713.                         DRM_INFO("(%i, %i %ux%u) ", rects[i].x, rects[i].y,
  1714.                                  rects[i].w, rects[i].h);
  1715.                 DRM_INFO("\n");
  1716.         }
  1717. #endif
  1718.  
  1719.         list_for_each_entry(con, &dev->mode_config.connector_list, head) {
  1720.                 du = vmw_connector_to_du(con);
  1721.                 if (num > du->unit) {
  1722.                         du->pref_width = rects[du->unit].w;
  1723.                         du->pref_height = rects[du->unit].h;
  1724.                         du->pref_active = true;
  1725.                         du->gui_x = rects[du->unit].x;
  1726.                         du->gui_y = rects[du->unit].y;
  1727.                 } else {
  1728.                         du->pref_width = 800;
  1729.                         du->pref_height = 600;
  1730.                         du->pref_active = false;
  1731.                 }
  1732.                 con->status = vmw_du_connector_detect(con, true);
  1733.         }
  1734.  
  1735.         mutex_unlock(&dev->mode_config.mutex);
  1736.  
  1737.         return 0;
  1738. }
  1739.  
  1740. #if 0
  1741. int vmw_du_page_flip(struct drm_crtc *crtc,
  1742.                      struct drm_framebuffer *fb,
  1743.                      struct drm_pending_vblank_event *event,
  1744.                      uint32_t page_flip_flags)
  1745. {
  1746.         struct vmw_private *dev_priv = vmw_priv(crtc->dev);
  1747.         struct drm_framebuffer *old_fb = crtc->fb;
  1748.         struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
  1749.         struct drm_file *file_priv ;
  1750.         struct vmw_fence_obj *fence = NULL;
  1751.         struct drm_clip_rect clips;
  1752.         int ret;
  1753.  
  1754.         if (event == NULL)
  1755.                 return -EINVAL;
  1756.  
  1757.         /* require ScreenObject support for page flipping */
  1758.         if (!dev_priv->sou_priv)
  1759.                 return -ENOSYS;
  1760.  
  1761.         file_priv = event->base.file_priv;
  1762.         if (!vmw_kms_screen_object_flippable(dev_priv, crtc))
  1763.                 return -EINVAL;
  1764.  
  1765.         crtc->fb = fb;
  1766.  
  1767.         /* do a full screen dirty update */
  1768.         clips.x1 = clips.y1 = 0;
  1769.         clips.x2 = fb->width;
  1770.         clips.y2 = fb->height;
  1771.  
  1772.         if (vfb->dmabuf)
  1773.                 ret = do_dmabuf_dirty_sou(file_priv, dev_priv, vfb,
  1774.                                           0, 0, &clips, 1, 1, &fence);
  1775.         else
  1776.                 ret = do_surface_dirty_sou(dev_priv, file_priv, vfb,
  1777.                                            0, 0, &clips, 1, 1, &fence);
  1778.  
  1779.  
  1780.         if (ret != 0)
  1781.                 goto out_no_fence;
  1782.         if (!fence) {
  1783.                 ret = -EINVAL;
  1784.                 goto out_no_fence;
  1785.         }
  1786.  
  1787.         ret = vmw_event_fence_action_queue(file_priv, fence,
  1788.                                            &event->base,
  1789.                                            &event->event.tv_sec,
  1790.                                            &event->event.tv_usec,
  1791.                                            true);
  1792.  
  1793.         /*
  1794.          * No need to hold on to this now. The only cleanup
  1795.          * we need to do if we fail is unref the fence.
  1796.          */
  1797.         vmw_fence_obj_unreference(&fence);
  1798.  
  1799.         if (vmw_crtc_to_du(crtc)->is_implicit)
  1800.                 vmw_kms_screen_object_update_implicit_fb(dev_priv, crtc);
  1801.  
  1802.         return ret;
  1803.  
  1804. out_no_fence:
  1805.         crtc->fb = old_fb;
  1806.         return ret;
  1807. }
  1808. #endif
  1809.  
  1810. void vmw_du_crtc_save(struct drm_crtc *crtc)
  1811. {
  1812. }
  1813.  
  1814. void vmw_du_crtc_restore(struct drm_crtc *crtc)
  1815. {
  1816. }
  1817.  
  1818. void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
  1819.                            u16 *r, u16 *g, u16 *b,
  1820.                            uint32_t start, uint32_t size)
  1821. {
  1822.         struct vmw_private *dev_priv = vmw_priv(crtc->dev);
  1823.         int i;
  1824.  
  1825.         for (i = 0; i < size; i++) {
  1826.                 DRM_DEBUG("%d r/g/b = 0x%04x / 0x%04x / 0x%04x\n", i,
  1827.                           r[i], g[i], b[i]);
  1828.                 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 0, r[i] >> 8);
  1829.                 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8);
  1830.                 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8);
  1831.         }
  1832. }
  1833.  
  1834. void vmw_du_connector_dpms(struct drm_connector *connector, int mode)
  1835. {
  1836. }
  1837.  
  1838. void vmw_du_connector_save(struct drm_connector *connector)
  1839. {
  1840. }
  1841.  
  1842. void vmw_du_connector_restore(struct drm_connector *connector)
  1843. {
  1844. }
  1845.  
  1846. enum drm_connector_status
  1847. vmw_du_connector_detect(struct drm_connector *connector, bool force)
  1848. {
  1849.         uint32_t num_displays;
  1850.         struct drm_device *dev = connector->dev;
  1851.         struct vmw_private *dev_priv = vmw_priv(dev);
  1852.         struct vmw_display_unit *du = vmw_connector_to_du(connector);
  1853.  
  1854.         mutex_lock(&dev_priv->hw_mutex);
  1855.         num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS);
  1856.         mutex_unlock(&dev_priv->hw_mutex);
  1857.  
  1858.         return ((vmw_connector_to_du(connector)->unit < num_displays &&
  1859.                  du->pref_active) ?
  1860.                 connector_status_connected : connector_status_disconnected);
  1861. }
  1862.  
  1863. static struct drm_display_mode vmw_kms_connector_builtin[] = {
  1864.         /* 640x480@60Hz */
  1865.         { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
  1866.                    752, 800, 0, 480, 489, 492, 525, 0,
  1867.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
  1868.         /* 800x600@60Hz */
  1869.         { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
  1870.                    968, 1056, 0, 600, 601, 605, 628, 0,
  1871.                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1872.         /* 1024x768@60Hz */
  1873.         { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
  1874.                    1184, 1344, 0, 768, 771, 777, 806, 0,
  1875.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
  1876.         /* 1152x864@75Hz */
  1877.         { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
  1878.                    1344, 1600, 0, 864, 865, 868, 900, 0,
  1879.                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1880.         /* 1280x768@60Hz */
  1881.         { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
  1882.                    1472, 1664, 0, 768, 771, 778, 798, 0,
  1883.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1884.         /* 1280x800@60Hz */
  1885.         { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
  1886.                    1480, 1680, 0, 800, 803, 809, 831, 0,
  1887.                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
  1888.         /* 1280x960@60Hz */
  1889.         { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
  1890.                    1488, 1800, 0, 960, 961, 964, 1000, 0,
  1891.                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1892.         /* 1280x1024@60Hz */
  1893.         { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
  1894.                    1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
  1895.                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1896.         /* 1360x768@60Hz */
  1897.         { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
  1898.                    1536, 1792, 0, 768, 771, 777, 795, 0,
  1899.                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1900.         /* 1440x1050@60Hz */
  1901.         { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
  1902.                    1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
  1903.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1904.         /* 1440x900@60Hz */
  1905.         { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
  1906.                    1672, 1904, 0, 900, 903, 909, 934, 0,
  1907.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1908.         /* 1600x1200@60Hz */
  1909.         { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
  1910.                    1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
  1911.                    DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1912.         /* 1680x1050@60Hz */
  1913.         { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
  1914.                    1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
  1915.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1916.         /* 1792x1344@60Hz */
  1917.         { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
  1918.                    2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
  1919.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1920.         /* 1853x1392@60Hz */
  1921.         { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
  1922.                    2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
  1923.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1924.     { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
  1925.            2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
  1926.            DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
  1927.            .vrefresh = 60, },
  1928.         /* 1920x1200@60Hz */
  1929.         { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
  1930.                    2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
  1931.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1932.         /* 1920x1440@60Hz */
  1933.         { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
  1934.                    2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
  1935.                    DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
  1936.         /* 2560x1600@60Hz */
  1937. /*   { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
  1938.                    3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
  1939.            DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, */
  1940.         /* Terminate */
  1941.         { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) },
  1942. };
  1943.  
  1944. /**
  1945.  * vmw_guess_mode_timing - Provide fake timings for a
  1946.  * 60Hz vrefresh mode.
  1947.  *
  1948.  * @mode - Pointer to a struct drm_display_mode with hdisplay and vdisplay
  1949.  * members filled in.
  1950.  */
  1951. static void vmw_guess_mode_timing(struct drm_display_mode *mode)
  1952. {
  1953.         mode->hsync_start = mode->hdisplay + 50;
  1954.         mode->hsync_end = mode->hsync_start + 50;
  1955.         mode->htotal = mode->hsync_end + 50;
  1956.  
  1957.         mode->vsync_start = mode->vdisplay + 50;
  1958.         mode->vsync_end = mode->vsync_start + 50;
  1959.         mode->vtotal = mode->vsync_end + 50;
  1960.  
  1961.         mode->clock = (u32)mode->htotal * (u32)mode->vtotal / 100 * 6;
  1962.         mode->vrefresh = drm_mode_vrefresh(mode);
  1963. }
  1964.  
  1965.  
  1966. int vmw_du_connector_fill_modes(struct drm_connector *connector,
  1967.                                 uint32_t max_width, uint32_t max_height)
  1968. {
  1969.         struct vmw_display_unit *du = vmw_connector_to_du(connector);
  1970.         struct drm_device *dev = connector->dev;
  1971.         struct vmw_private *dev_priv = vmw_priv(dev);
  1972.         struct drm_display_mode *mode = NULL;
  1973.         struct drm_display_mode *bmode;
  1974.         struct drm_display_mode prefmode = { DRM_MODE("preferred",
  1975.                 DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
  1976.                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1977.                 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
  1978.         };
  1979.         int i;
  1980.  
  1981.         /* Add preferred mode */
  1982.         {
  1983.                 mode = drm_mode_duplicate(dev, &prefmode);
  1984.                 if (!mode)
  1985.                         return 0;
  1986.                 mode->hdisplay = du->pref_width;
  1987.                 mode->vdisplay = du->pref_height;
  1988.                 vmw_guess_mode_timing(mode);
  1989.  
  1990.                 if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2,
  1991.                                                mode->vdisplay)) {
  1992.                         drm_mode_probed_add(connector, mode);
  1993.                 } else {
  1994.                         drm_mode_destroy(dev, mode);
  1995.                         mode = NULL;
  1996.                 }
  1997.  
  1998.                 if (du->pref_mode) {
  1999.                         list_del_init(&du->pref_mode->head);
  2000.                         drm_mode_destroy(dev, du->pref_mode);
  2001.                 }
  2002.  
  2003.                 /* mode might be null here, this is intended */
  2004.                 du->pref_mode = mode;
  2005.         }
  2006.  
  2007.         for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) {
  2008.                 bmode = &vmw_kms_connector_builtin[i];
  2009.                 if (bmode->hdisplay > max_width ||
  2010.                     bmode->vdisplay > max_height)
  2011.                         continue;
  2012.  
  2013.                 if (!vmw_kms_validate_mode_vram(dev_priv, bmode->hdisplay * 2,
  2014.                                                 bmode->vdisplay))
  2015.                         continue;
  2016.  
  2017.                 mode = drm_mode_duplicate(dev, bmode);
  2018.                 if (!mode)
  2019.                         return 0;
  2020.                 mode->vrefresh = drm_mode_vrefresh(mode);
  2021.  
  2022.                 drm_mode_probed_add(connector, mode);
  2023.         }
  2024.  
  2025.         /* Move the prefered mode first, help apps pick the right mode. */
  2026.         if (du->pref_mode)
  2027.                 list_move(&du->pref_mode->head, &connector->probed_modes);
  2028.  
  2029.         drm_mode_connector_list_update(connector);
  2030.  
  2031.         return 1;
  2032. }
  2033.  
  2034. int vmw_du_connector_set_property(struct drm_connector *connector,
  2035.                                   struct drm_property *property,
  2036.                                   uint64_t val)
  2037. {
  2038.         return 0;
  2039. }
  2040.  
  2041. #if 0
  2042. int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
  2043.                                 struct drm_file *file_priv)
  2044. {
  2045.         struct vmw_private *dev_priv = vmw_priv(dev);
  2046.         struct drm_vmw_update_layout_arg *arg =
  2047.                 (struct drm_vmw_update_layout_arg *)data;
  2048.         struct vmw_master *vmaster = vmw_master(file_priv->master);
  2049.         void __user *user_rects;
  2050.         struct drm_vmw_rect *rects;
  2051.         unsigned rects_size;
  2052.         int ret;
  2053.         int i;
  2054.         struct drm_mode_config *mode_config = &dev->mode_config;
  2055.  
  2056.         ret = ttm_read_lock(&vmaster->lock, true);
  2057.         if (unlikely(ret != 0))
  2058.                 return ret;
  2059.  
  2060.         if (!arg->num_outputs) {
  2061.                 struct drm_vmw_rect def_rect = {0, 0, 800, 600};
  2062.                 vmw_du_update_layout(dev_priv, 1, &def_rect);
  2063.                 goto out_unlock;
  2064.         }
  2065.  
  2066.         rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
  2067.         rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
  2068.                         GFP_KERNEL);
  2069.         if (unlikely(!rects)) {
  2070.                 ret = -ENOMEM;
  2071.                 goto out_unlock;
  2072.         }
  2073.  
  2074.         user_rects = (void __user *)(unsigned long)arg->rects;
  2075.         ret = copy_from_user(rects, user_rects, rects_size);
  2076.         if (unlikely(ret != 0)) {
  2077.                 DRM_ERROR("Failed to get rects.\n");
  2078.                 ret = -EFAULT;
  2079.                 goto out_free;
  2080.         }
  2081.  
  2082.         for (i = 0; i < arg->num_outputs; ++i) {
  2083.                 if (rects[i].x < 0 ||
  2084.                     rects[i].y < 0 ||
  2085.                     rects[i].x + rects[i].w > mode_config->max_width ||
  2086.                     rects[i].y + rects[i].h > mode_config->max_height) {
  2087.                         DRM_ERROR("Invalid GUI layout.\n");
  2088.                         ret = -EINVAL;
  2089.                         goto out_free;
  2090.                 }
  2091.         }
  2092.  
  2093.         vmw_du_update_layout(dev_priv, arg->num_outputs, rects);
  2094.  
  2095. out_free:
  2096.         kfree(rects);
  2097. out_unlock:
  2098.         ttm_read_unlock(&vmaster->lock);
  2099.         return ret;
  2100. }
  2101. #endif
  2102.