Subversion Repositories Kolibri OS

Rev

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