OSDN Git Service

drm/vmwgfx: Add basic support for SVGA3
authorZack Rusin <zackr@vmware.com>
Wed, 5 May 2021 19:10:07 +0000 (15:10 -0400)
committerZack Rusin <zackr@vmware.com>
Tue, 11 May 2021 17:37:15 +0000 (13:37 -0400)
SVGA3 is the next version of our PCI device. Some of the changes
include using MMIO for register accesses instead of ioports,
deprecating the FIFO MMIO and removing a lot of the old and
legacy functionality. SVGA3 doesn't support guest backed
objects right now so everything except 3D is working.

v2: Fixes all the static analyzer warnings

Signed-off-by: Zack Rusin <zackr@vmware.com>
Cc: Martin Krastev <krastevm@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210505191007.305872-1-zackr@vmware.com
25 files changed:
drivers/gpu/drm/vmwgfx/device_include/svga_reg.h
drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c
drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
drivers/gpu/drm/vmwgfx/vmwgfx_irq.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
drivers/gpu/drm/vmwgfx/vmwgfx_reg.h
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
drivers/gpu/drm/vmwgfx/vmwgfx_so.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
drivers/gpu/drm/vmwgfx/vmwgfx_validation.c

index 19fb9e3..193a57f 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
 /**********************************************************
- * Copyright 1998-2015 VMware, Inc.
+ * Copyright 1998-2021 VMware, Inc.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -98,6 +98,10 @@ typedef uint32 SVGAMobId;
 #define SVGA_MAGIC         0x900000UL
 #define SVGA_MAKE_ID(ver)  (SVGA_MAGIC << 8 | (ver))
 
+/* Version 3 has the control bar instead of the FIFO */
+#define SVGA_VERSION_3     3
+#define SVGA_ID_3          SVGA_MAKE_ID(SVGA_VERSION_3)
+
 /* Version 2 let the address of the frame buffer be unsigned on Win32 */
 #define SVGA_VERSION_2     2
 #define SVGA_ID_2          SVGA_MAKE_ID(SVGA_VERSION_2)
@@ -129,11 +133,12 @@ typedef uint32 SVGAMobId;
  * Interrupts are only supported when the
  * SVGA_CAP_IRQMASK capability is present.
  */
-#define SVGA_IRQFLAG_ANY_FENCE            0x1    /* Any fence was passed */
-#define SVGA_IRQFLAG_FIFO_PROGRESS        0x2    /* Made forward progress in the FIFO */
-#define SVGA_IRQFLAG_FENCE_GOAL           0x4    /* SVGA_FIFO_FENCE_GOAL reached */
-#define SVGA_IRQFLAG_COMMAND_BUFFER       0x8    /* Command buffer completed */
-#define SVGA_IRQFLAG_ERROR                0x10   /* Error while processing commands */
+#define SVGA_IRQFLAG_ANY_FENCE            (1 << 0) /* Any fence was passed */
+#define SVGA_IRQFLAG_FIFO_PROGRESS        (1 << 1) /* Made forward progress in the FIFO */
+#define SVGA_IRQFLAG_FENCE_GOAL           (1 << 2) /* SVGA_FIFO_FENCE_GOAL reached */
+#define SVGA_IRQFLAG_COMMAND_BUFFER       (1 << 3) /* Command buffer completed */
+#define SVGA_IRQFLAG_ERROR                (1 << 4) /* Error while processing commands */
+#define SVGA_IRQFLAG_MAX                  (1 << 5)
 
 /*
  * The byte-size is the size of the actual cursor data,
@@ -286,7 +291,32 @@ enum {
     */
    SVGA_REG_GBOBJECT_MEM_SIZE_KB = 76,
 
-   SVGA_REG_TOP = 77,               /* Must be 1 more than the last register */
+   /*
+    +    * These registers are for the addresses of the memory BARs for SVGA3
+    */
+   SVGA_REG_REGS_START_HIGH32 = 77,
+   SVGA_REG_REGS_START_LOW32 = 78,
+   SVGA_REG_FB_START_HIGH32 = 79,
+   SVGA_REG_FB_START_LOW32 = 80,
+
+   /*
+    * A hint register that recommends which quality level the guest should
+    * currently use to define multisample surfaces.
+    *
+    * If the register is SVGA_REG_MSHINT_DISABLED,
+    * the guest is only allowed to use SVGA3D_MS_QUALITY_FULL.
+    *
+    * Otherwise, this is a live value that can change while the VM is
+    * powered on with the hint suggestion for which quality level the guest
+    * should be using.  Guests are free to ignore the hint and use either
+    * RESOLVE or FULL quality.
+    */
+   SVGA_REG_MSHINT = 81,
+
+   SVGA_REG_IRQ_STATUS = 82,
+   SVGA_REG_DIRTY_TRACKING = 83,
+
+   SVGA_REG_TOP = 84,               /* Must be 1 more than the last register */
 
    SVGA_PALETTE_BASE = 1024,        /* Base of SVGA color map */
    /* Next 768 (== 256*3) registers exist for colormap */
@@ -310,6 +340,17 @@ typedef enum SVGARegGuestDriverId {
    SVGA_REG_GUEST_DRIVER_ID_SUBMIT  = MAX_UINT32,
 } SVGARegGuestDriverId;
 
+typedef enum SVGARegMSHint {
+   SVGA_REG_MSHINT_DISABLED = 0,
+   SVGA_REG_MSHINT_FULL     = 1,
+   SVGA_REG_MSHINT_RESOLVED = 2,
+} SVGARegMSHint;
+
+typedef enum SVGARegDirtyTracking {
+   SVGA_REG_DIRTY_TRACKING_PER_IMAGE = 0,
+   SVGA_REG_DIRTY_TRACKING_PER_SURFACE = 1,
+} SVGARegDirtyTracking;
+
 
 /*
  * Guest memory regions (GMRs):
index 81f525a..05b3248 100644 (file)
@@ -788,7 +788,7 @@ static void vmw_collect_dirty_view_ids(struct vmw_ctx_binding_state *cbs,
 }
 
 /**
- * vmw_binding_emit_set_sr - Issue delayed DX shader resource binding commands
+ * vmw_emit_set_sr - Issue delayed DX shader resource binding commands
  *
  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
  * @shader_slot: The shader slot of the binding.
@@ -832,7 +832,7 @@ static int vmw_emit_set_sr(struct vmw_ctx_binding_state *cbs,
 }
 
 /**
- * vmw_binding_emit_set_rt - Issue delayed DX rendertarget binding commands
+ * vmw_emit_set_rt - Issue delayed DX rendertarget binding commands
  *
  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
  */
@@ -1024,7 +1024,7 @@ static void vmw_collect_dirty_vbs(struct vmw_ctx_binding_state *cbs,
 }
 
 /**
- * vmw_binding_emit_set_vb - Issue delayed vertex buffer binding commands
+ * vmw_emit_set_vb - Issue delayed vertex buffer binding commands
  *
  * @cbs: Pointer to the context's struct vmw_ctx_binding_state
  *
@@ -1394,7 +1394,7 @@ struct list_head *vmw_binding_state_list(struct vmw_ctx_binding_state *cbs)
 }
 
 /**
- * vmwgfx_binding_state_reset - clear a struct vmw_ctx_binding_state
+ * vmw_binding_state_reset - clear a struct vmw_ctx_binding_state
  *
  * @cbs: Pointer to the struct vmw_ctx_binding_state to be cleared
  *
index 3a438ae..cdbd5a8 100644 (file)
@@ -421,7 +421,7 @@ static int vmw_bo_cpu_blit_line(struct vmw_bo_blit_line_data *d,
 }
 
 /**
- * ttm_bo_cpu_blit - in-kernel cpu blit.
+ * vmw_bo_cpu_blit - in-kernel cpu blit.
  *
  * @dst: Destination buffer object.
  * @dst_offset: Destination offset of blit start in bytes.
index 4aa9738..04dd49c 100644 (file)
@@ -600,7 +600,7 @@ static void vmw_user_bo_release(struct ttm_base_object **p_base)
 
 
 /**
- * vmw_user_bo_ref_obj-release - TTM synccpu reference object release callback
+ * vmw_user_bo_ref_obj_release - TTM synccpu reference object release callback
  * for vmw user buffer objects
  *
  * @base: Pointer to the TTM base object
index 20246a7..027d7d5 100644 (file)
 
 #include "vmwgfx_drv.h"
 
-struct vmw_temp_set_context {
-       SVGA3dCmdHeader header;
-       SVGA3dCmdDXTempSetContext body;
-};
-
 bool vmw_supports_3d(struct vmw_private *dev_priv)
 {
        uint32_t fifo_min, hwversion;
-       const struct vmw_fifo_state *fifo = &dev_priv->fifo;
+       const struct vmw_fifo_state *fifo = dev_priv->fifo;
 
        if (!(dev_priv->capabilities & SVGA_CAP_3D))
                return false;
@@ -61,6 +56,8 @@ bool vmw_supports_3d(struct vmw_private *dev_priv)
        if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO))
                return false;
 
+       BUG_ON(vmw_is_svga_v3(dev_priv));
+
        fifo_min = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MIN);
        if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int))
                return false;
@@ -98,16 +95,20 @@ bool vmw_fifo_have_pitchlock(struct vmw_private *dev_priv)
        return false;
 }
 
-int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
+struct vmw_fifo_state *vmw_fifo_create(struct vmw_private *dev_priv)
 {
+       struct vmw_fifo_state *fifo;
        uint32_t max;
        uint32_t min;
 
-       fifo->dx = false;
+       if (!dev_priv->fifo_mem)
+               return NULL;
+
+       fifo = kzalloc(sizeof(*fifo), GFP_KERNEL);
        fifo->static_buffer_size = VMWGFX_FIFO_STATIC_SIZE;
        fifo->static_buffer = vmalloc(fifo->static_buffer_size);
        if (unlikely(fifo->static_buffer == NULL))
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        fifo->dynamic_buffer = NULL;
        fifo->reserved_size = 0;
@@ -115,20 +116,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
 
        mutex_init(&fifo->fifo_mutex);
        init_rwsem(&fifo->rwsem);
-
-       DRM_INFO("width %d\n", vmw_read(dev_priv, SVGA_REG_WIDTH));
-       DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT));
-       DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL));
-
-       dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE);
-       dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE);
-       dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES);
-
-       vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE_ENABLE |
-                 SVGA_REG_ENABLE_HIDE);
-
-       vmw_write(dev_priv, SVGA_REG_TRACES, 0);
-
        min = 4;
        if (dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)
                min = vmw_read(dev_priv, SVGA_REG_MEM_REGS);
@@ -155,35 +142,23 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
                 (unsigned int) max,
                 (unsigned int) min,
                 (unsigned int) fifo->capabilities);
-
-       atomic_set(&dev_priv->marker_seq, dev_priv->last_read_seqno);
-       vmw_fifo_mem_write(dev_priv, SVGA_FIFO_FENCE, dev_priv->last_read_seqno);
-
-       return 0;
+       return fifo;
 }
 
 void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason)
 {
        u32 *fifo_mem = dev_priv->fifo_mem;
-
-       if (cmpxchg(fifo_mem + SVGA_FIFO_BUSY, 0, 1) == 0)
+       if (fifo_mem && cmpxchg(fifo_mem + SVGA_FIFO_BUSY, 0, 1) == 0)
                vmw_write(dev_priv, SVGA_REG_SYNC, reason);
+
 }
 
-void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
+void vmw_fifo_destroy(struct vmw_private *dev_priv)
 {
-       vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC);
-       while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0)
-               ;
-
-       dev_priv->last_read_seqno = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_FENCE);
+       struct vmw_fifo_state *fifo = dev_priv->fifo;
 
-       vmw_write(dev_priv, SVGA_REG_CONFIG_DONE,
-                 dev_priv->config_done_state);
-       vmw_write(dev_priv, SVGA_REG_ENABLE,
-                 dev_priv->enable_state);
-       vmw_write(dev_priv, SVGA_REG_TRACES,
-                 dev_priv->traces_state);
+       if (!fifo)
+               return;
 
        if (likely(fifo->static_buffer != NULL)) {
                vfree(fifo->static_buffer);
@@ -194,6 +169,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo)
                vfree(fifo->dynamic_buffer);
                fifo->dynamic_buffer = NULL;
        }
+       kfree(fifo);
+       dev_priv->fifo = NULL;
 }
 
 static bool vmw_fifo_is_full(struct vmw_private *dev_priv, uint32_t bytes)
@@ -289,7 +266,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv,
 static void *vmw_local_fifo_reserve(struct vmw_private *dev_priv,
                                    uint32_t bytes)
 {
-       struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
+       struct vmw_fifo_state *fifo_state = dev_priv->fifo;
        u32  *fifo_mem = dev_priv->fifo_mem;
        uint32_t max;
        uint32_t min;
@@ -438,16 +415,12 @@ static void vmw_fifo_slow_copy(struct vmw_fifo_state *fifo_state,
 
 static void vmw_local_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes)
 {
-       struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
+       struct vmw_fifo_state *fifo_state = dev_priv->fifo;
        uint32_t next_cmd = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_NEXT_CMD);
        uint32_t max = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MAX);
        uint32_t min = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_MIN);
        bool reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE;
 
-       if (fifo_state->dx)
-               bytes += sizeof(struct vmw_temp_set_context);
-
-       fifo_state->dx = false;
        BUG_ON((bytes & 3) != 0);
        BUG_ON(bytes > fifo_state->reserved_size);
 
@@ -495,7 +468,7 @@ void vmw_cmd_commit(struct vmw_private *dev_priv, uint32_t bytes)
 
 
 /**
- * vmw_fifo_commit_flush - Commit fifo space and flush any buffered commands.
+ * vmw_cmd_commit_flush - Commit fifo space and flush any buffered commands.
  *
  * @dev_priv: Pointer to device private structure.
  * @bytes: Number of bytes to commit.
@@ -509,7 +482,7 @@ void vmw_cmd_commit_flush(struct vmw_private *dev_priv, uint32_t bytes)
 }
 
 /**
- * vmw_fifo_flush - Flush any buffered commands and make sure command processing
+ * vmw_cmd_flush - Flush any buffered commands and make sure command processing
  * starts.
  *
  * @dev_priv: Pointer to device private structure.
@@ -527,7 +500,6 @@ int vmw_cmd_flush(struct vmw_private *dev_priv, bool interruptible)
 
 int vmw_cmd_send_fence(struct vmw_private *dev_priv, uint32_t *seqno)
 {
-       struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
        struct svga_fifo_cmd_fence *cmd_fence;
        u32 *fm;
        int ret = 0;
@@ -546,7 +518,7 @@ int vmw_cmd_send_fence(struct vmw_private *dev_priv, uint32_t *seqno)
                *seqno = atomic_add_return(1, &dev_priv->marker_seq);
        } while (*seqno == 0);
 
-       if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE)) {
+       if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE)) {
 
                /*
                 * Don't request hardware to send a fence. The
@@ -561,22 +533,22 @@ int vmw_cmd_send_fence(struct vmw_private *dev_priv, uint32_t *seqno)
        cmd_fence = (struct svga_fifo_cmd_fence *) fm;
        cmd_fence->fence = *seqno;
        vmw_cmd_commit_flush(dev_priv, bytes);
-       vmw_update_seqno(dev_priv, fifo_state);
+       vmw_update_seqno(dev_priv);
 
 out_err:
        return ret;
 }
 
 /**
- * vmw_fifo_emit_dummy_legacy_query - emits a dummy query to the fifo using
+ * vmw_cmd_emit_dummy_legacy_query - emits a dummy query to the fifo using
  * legacy query commands.
  *
  * @dev_priv: The device private structure.
  * @cid: The hardware context id used for the query.
  *
- * See the vmw_fifo_emit_dummy_query documentation.
+ * See the vmw_cmd_emit_dummy_query documentation.
  */
-static int vmw_fifo_emit_dummy_legacy_query(struct vmw_private *dev_priv,
+static int vmw_cmd_emit_dummy_legacy_query(struct vmw_private *dev_priv,
                                            uint32_t cid)
 {
        /*
@@ -614,16 +586,16 @@ static int vmw_fifo_emit_dummy_legacy_query(struct vmw_private *dev_priv,
 }
 
 /**
- * vmw_fifo_emit_dummy_gb_query - emits a dummy query to the fifo using
+ * vmw_cmd_emit_dummy_gb_query - emits a dummy query to the fifo using
  * guest-backed resource query commands.
  *
  * @dev_priv: The device private structure.
  * @cid: The hardware context id used for the query.
  *
- * See the vmw_fifo_emit_dummy_query documentation.
+ * See the vmw_cmd_emit_dummy_query documentation.
  */
-static int vmw_fifo_emit_dummy_gb_query(struct vmw_private *dev_priv,
-                                       uint32_t cid)
+static int vmw_cmd_emit_dummy_gb_query(struct vmw_private *dev_priv,
+                                      uint32_t cid)
 {
        /*
         * A query wait without a preceding query end will
@@ -656,7 +628,7 @@ static int vmw_fifo_emit_dummy_gb_query(struct vmw_private *dev_priv,
 
 
 /**
- * vmw_fifo_emit_dummy_gb_query - emits a dummy query to the fifo using
+ * vmw_cmd_emit_dummy_query - emits a dummy query to the fifo using
  * appropriate resource query commands.
  *
  * @dev_priv: The device private structure.
@@ -677,7 +649,27 @@ int vmw_cmd_emit_dummy_query(struct vmw_private *dev_priv,
                              uint32_t cid)
 {
        if (dev_priv->has_mob)
-               return vmw_fifo_emit_dummy_gb_query(dev_priv, cid);
+               return vmw_cmd_emit_dummy_gb_query(dev_priv, cid);
 
-       return vmw_fifo_emit_dummy_legacy_query(dev_priv, cid);
+       return vmw_cmd_emit_dummy_legacy_query(dev_priv, cid);
+}
+
+
+/**
+ * vmw_cmd_supported - returns true if the given device supports
+ * command queues.
+ *
+ * @vmw: The device private structure.
+ *
+ * Returns true if we can issue commands.
+ */
+bool vmw_cmd_supported(struct vmw_private *vmw)
+{
+       if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS |
+                                 SVGA_CAP_CMD_BUFFERS_2)) != 0)
+               return true;
+       /*
+        * We have FIFO cmd's
+        */
+       return vmw->fifo_mem != NULL;
 }
index 2e23e53..05ca310 100644 (file)
@@ -295,7 +295,7 @@ void vmw_cmdbuf_header_free(struct vmw_cmdbuf_header *header)
 
 
 /**
- * vmw_cmbuf_header_submit: Submit a command buffer to hardware.
+ * vmw_cmdbuf_header_submit: Submit a command buffer to hardware.
  *
  * @header: The header of the buffer to submit.
  */
@@ -620,7 +620,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
 }
 
 /**
- * vmw_cmdbuf_man idle - Check whether the command buffer manager is idle.
+ * vmw_cmdbuf_man_idle - Check whether the command buffer manager is idle.
  *
  * @man: The command buffer manager.
  * @check_preempted: Check also the preempted queue for pending command buffers.
index d782b49..b40aa00 100644 (file)
@@ -653,7 +653,7 @@ int vmw_cotable_notify(struct vmw_resource *res, int id)
 }
 
 /**
- * vmw_cotable_add_view - add a view to the cotable's list of active views.
+ * vmw_cotable_add_resource - add a view to the cotable's list of active views.
  *
  * @res: pointer struct vmw_resource representing the cotable.
  * @head: pointer to the struct list_head member of the resource, dedicated
index 22a2874..4904100 100644 (file)
@@ -50,7 +50,7 @@
 #define VMWGFX_VALIDATION_MEM_GRAN (16*PAGE_SIZE)
 
 
-/**
+/*
  * Fully encoded drm commands. Might move to vmw_drm.h
  */
 
@@ -246,6 +246,7 @@ static const struct drm_ioctl_desc vmw_ioctls[] = {
 
 static const struct pci_device_id vmw_pci_id_list[] = {
        { PCI_DEVICE(0x15ad, VMWGFX_PCI_ID_SVGA2) },
+       { PCI_DEVICE(0x15ad, VMWGFX_PCI_ID_SVGA3) },
        { }
 };
 MODULE_DEVICE_TABLE(pci, vmw_pci_id_list);
@@ -393,6 +394,60 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv)
        return ret;
 }
 
+static int vmw_device_init(struct vmw_private *dev_priv)
+{
+       bool uses_fb_traces = false;
+
+       DRM_INFO("width %d\n", vmw_read(dev_priv, SVGA_REG_WIDTH));
+       DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT));
+       DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL));
+
+       dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE);
+       dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE);
+       dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES);
+
+       vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE_ENABLE |
+                 SVGA_REG_ENABLE_HIDE);
+
+       uses_fb_traces = !vmw_cmd_supported(dev_priv) &&
+                        (dev_priv->capabilities & SVGA_CAP_TRACES) != 0;
+
+       vmw_write(dev_priv, SVGA_REG_TRACES, uses_fb_traces);
+       dev_priv->fifo = vmw_fifo_create(dev_priv);
+       if (IS_ERR(dev_priv->fifo)) {
+               int err = PTR_ERR(dev_priv->fifo);
+               dev_priv->fifo = NULL;
+               return err;
+       } else if (!dev_priv->fifo) {
+               vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1);
+       }
+
+       dev_priv->last_read_seqno = vmw_fence_read(dev_priv);
+       atomic_set(&dev_priv->marker_seq, dev_priv->last_read_seqno);
+       return 0;
+}
+
+static void vmw_device_fini(struct vmw_private *vmw)
+{
+       /*
+        * Legacy sync
+        */
+       vmw_write(vmw, SVGA_REG_SYNC, SVGA_SYNC_GENERIC);
+       while (vmw_read(vmw, SVGA_REG_BUSY) != 0)
+               ;
+
+       vmw->last_read_seqno = vmw_fence_read(vmw);
+
+       vmw_write(vmw, SVGA_REG_CONFIG_DONE,
+                 vmw->config_done_state);
+       vmw_write(vmw, SVGA_REG_ENABLE,
+                 vmw->enable_state);
+       vmw_write(vmw, SVGA_REG_TRACES,
+                 vmw->traces_state);
+
+       vmw_fifo_destroy(vmw);
+}
+
 /**
  * vmw_request_device_late - Perform late device setup
  *
@@ -433,9 +488,9 @@ static int vmw_request_device(struct vmw_private *dev_priv)
 {
        int ret;
 
-       ret = vmw_fifo_init(dev_priv, &dev_priv->fifo);
+       ret = vmw_device_init(dev_priv);
        if (unlikely(ret != 0)) {
-               DRM_ERROR("Unable to initialize FIFO.\n");
+               DRM_ERROR("Unable to initialize the device.\n");
                return ret;
        }
        vmw_fence_fifo_up(dev_priv->fman);
@@ -469,7 +524,7 @@ out_no_query_bo:
                vmw_cmdbuf_man_destroy(dev_priv->cman);
 out_no_mob:
        vmw_fence_fifo_down(dev_priv->fman);
-       vmw_fifo_release(dev_priv, &dev_priv->fifo);
+       vmw_device_fini(dev_priv);
        return ret;
 }
 
@@ -517,7 +572,7 @@ static void vmw_release_device_late(struct vmw_private *dev_priv)
        if (dev_priv->cman)
                vmw_cmdbuf_man_destroy(dev_priv->cman);
 
-       vmw_fifo_release(dev_priv, &dev_priv->fifo);
+       vmw_device_fini(dev_priv);
 }
 
 /*
@@ -638,6 +693,8 @@ static void vmw_vram_manager_fini(struct vmw_private *dev_priv)
 static int vmw_setup_pci_resources(struct vmw_private *dev,
                                   unsigned long pci_id)
 {
+       resource_size_t rmmio_start;
+       resource_size_t rmmio_size;
        resource_size_t fifo_start;
        resource_size_t fifo_size;
        int ret;
@@ -649,23 +706,45 @@ static int vmw_setup_pci_resources(struct vmw_private *dev,
        if (ret)
                return ret;
 
-       dev->io_start = pci_resource_start(pdev, 0);
-       dev->vram_start = pci_resource_start(pdev, 1);
-       dev->vram_size = pci_resource_len(pdev, 1);
-       fifo_start = pci_resource_start(pdev, 2);
-       fifo_size = pci_resource_len(pdev, 2);
-
-       DRM_INFO("FIFO at %pa size is %llu kiB\n",
-                &fifo_start, (uint64_t)fifo_size / 1024);
-       dev->fifo_mem = devm_memremap(dev->drm.dev,
-                                     fifo_start,
-                                     fifo_size,
-                                     MEMREMAP_WB);
-
-       if (IS_ERR(dev->fifo_mem)) {
-               DRM_ERROR("Failed mapping FIFO memory.\n");
+       dev->pci_id = pci_id;
+       if (pci_id == VMWGFX_PCI_ID_SVGA3) {
+               rmmio_start = pci_resource_start(pdev, 0);
+               rmmio_size = pci_resource_len(pdev, 0);
+               dev->vram_start = pci_resource_start(pdev, 2);
+               dev->vram_size = pci_resource_len(pdev, 2);
+
+               DRM_INFO("Register MMIO at 0x%pa size is %llu kiB\n",
+                        &rmmio_start, (uint64_t)rmmio_size / 1024);
+               dev->rmmio = devm_ioremap(dev->drm.dev,
+                                         rmmio_start,
+                                         rmmio_size);
+               if (IS_ERR(dev->rmmio)) {
+                       DRM_ERROR("Failed mapping registers mmio memory.\n");
+                       pci_release_regions(pdev);
+                       return PTR_ERR(dev->rmmio);
+               }
+       } else if (pci_id == VMWGFX_PCI_ID_SVGA2) {
+               dev->io_start = pci_resource_start(pdev, 0);
+               dev->vram_start = pci_resource_start(pdev, 1);
+               dev->vram_size = pci_resource_len(pdev, 1);
+               fifo_start = pci_resource_start(pdev, 2);
+               fifo_size = pci_resource_len(pdev, 2);
+
+               DRM_INFO("FIFO at %pa size is %llu kiB\n",
+                        &fifo_start, (uint64_t)fifo_size / 1024);
+               dev->fifo_mem = devm_memremap(dev->drm.dev,
+                                             fifo_start,
+                                             fifo_size,
+                                             MEMREMAP_WB);
+
+               if (IS_ERR(dev->fifo_mem)) {
+                       DRM_ERROR("Failed mapping FIFO memory.\n");
+                       pci_release_regions(pdev);
+                       return PTR_ERR(dev->fifo_mem);
+               }
+       } else {
                pci_release_regions(pdev);
-               return PTR_ERR(dev->fifo_mem);
+               return -EINVAL;
        }
 
        /*
@@ -684,13 +763,16 @@ static int vmw_detect_version(struct vmw_private *dev)
 {
        uint32_t svga_id;
 
-       vmw_write(dev, SVGA_REG_ID, SVGA_ID_2);
+       vmw_write(dev, SVGA_REG_ID, vmw_is_svga_v3(dev) ?
+                         SVGA_ID_3 : SVGA_ID_2);
        svga_id = vmw_read(dev, SVGA_REG_ID);
-       if (svga_id != SVGA_ID_2) {
+       if (svga_id != SVGA_ID_2 && svga_id != SVGA_ID_3) {
                DRM_ERROR("Unsupported SVGA ID 0x%x on chipset 0x%x\n",
                          svga_id, dev->vmw_chipset);
                return -ENOSYS;
        }
+       BUG_ON(vmw_is_svga_v3(dev) && (svga_id != SVGA_ID_3));
+       DRM_INFO("Running on SVGA version %d.\n", (svga_id & 0xff));
        return 0;
 }
 
@@ -703,7 +785,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
        struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
 
        dev_priv->vmw_chipset = pci_id;
-       dev_priv->last_read_seqno = (uint32_t) -100;
        dev_priv->drm.dev_private = dev_priv;
 
        mutex_init(&dev_priv->cmdbuf_mutex);
@@ -824,6 +905,8 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
        vmw_print_capabilities(dev_priv->capabilities);
        if (dev_priv->capabilities & SVGA_CAP_CAP2_REGISTER)
                vmw_print_capabilities2(dev_priv->capabilities2);
+       DRM_INFO("Supports command queues = %d\n",
+                vmw_cmd_supported((dev_priv)));
 
        ret = vmw_dma_masks(dev_priv);
        if (unlikely(ret != 0))
@@ -1390,8 +1473,7 @@ static int vmw_pm_restore(struct device *kdev)
        struct vmw_private *dev_priv = vmw_priv(dev);
        int ret;
 
-       vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
-       (void) vmw_read(dev_priv, SVGA_REG_ID);
+       vmw_detect_version(dev_priv);
 
        if (dev_priv->enable_fb)
                vmw_fifo_resource_inc(dev_priv);
@@ -1428,8 +1510,8 @@ static const struct file_operations vmwgfx_driver_fops = {
        .release = drm_release,
        .unlocked_ioctl = vmw_unlocked_ioctl,
        .mmap = vmw_mmap,
-       .poll = vmw_fops_poll,
-       .read = vmw_fops_read,
+       .poll = drm_poll,
+       .read = drm_read,
 #if defined(CONFIG_COMPAT)
        .compat_ioctl = vmw_compat_ioctl,
 #endif
index 2fb6898..dcdbc59 100644 (file)
@@ -66,6 +66,7 @@
 #define VMWGFX_ENABLE_SCREEN_TARGET_OTABLE 1
 
 #define VMWGFX_PCI_ID_SVGA2              0x0405
+#define VMWGFX_PCI_ID_SVGA3              0x0406
 
 /*
  * Perhaps we should have sysfs entries for these.
@@ -284,7 +285,6 @@ struct vmw_fifo_state {
        uint32_t capabilities;
        struct mutex fifo_mutex;
        struct rw_semaphore rwsem;
-       bool dx;
 };
 
 /**
@@ -485,14 +485,14 @@ struct vmw_private {
        struct drm_device drm;
        struct ttm_device bdev;
 
-       struct vmw_fifo_state fifo;
-
        struct drm_vma_offset_manager vma_manager;
+       unsigned long pci_id;
        u32 vmw_chipset;
        resource_size_t io_start;
        resource_size_t vram_start;
        resource_size_t vram_size;
        resource_size_t prim_bb_mem;
+       void __iomem *rmmio;
        u32 *fifo_mem;
        resource_size_t fifo_mem_size;
        uint32_t fb_max_width;
@@ -623,6 +623,7 @@ struct vmw_private {
         */
        struct vmw_otable_batch otable_batch;
 
+       struct vmw_fifo_state *fifo;
        struct vmw_cmdbuf_man *cman;
        DECLARE_BITMAP(irqthread_pending, VMW_IRQTHREAD_MAX);
 
@@ -646,6 +647,14 @@ static inline struct vmw_fpriv *vmw_fpriv(struct drm_file *file_priv)
 }
 
 /*
+ * SVGA v3 has mmio register access and lacks fifo cmds
+ */
+static inline bool vmw_is_svga_v3(const struct vmw_private *dev)
+{
+       return dev->pci_id == VMWGFX_PCI_ID_SVGA3;
+}
+
+/*
  * The locking here is fine-grained, so that it is performed once
  * for every read- and write operation. This is of course costly, but we
  * don't perform much register access in the timing critical paths anyway.
@@ -655,10 +664,14 @@ static inline struct vmw_fpriv *vmw_fpriv(struct drm_file *file_priv)
 static inline void vmw_write(struct vmw_private *dev_priv,
                             unsigned int offset, uint32_t value)
 {
-       spin_lock(&dev_priv->hw_lock);
-       outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT);
-       outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT);
-       spin_unlock(&dev_priv->hw_lock);
+       if (vmw_is_svga_v3(dev_priv)) {
+               iowrite32(value, dev_priv->rmmio + offset);
+       } else {
+               spin_lock(&dev_priv->hw_lock);
+               outl(offset, dev_priv->io_start + SVGA_INDEX_PORT);
+               outl(value, dev_priv->io_start + SVGA_VALUE_PORT);
+               spin_unlock(&dev_priv->hw_lock);
+       }
 }
 
 static inline uint32_t vmw_read(struct vmw_private *dev_priv,
@@ -666,10 +679,14 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv,
 {
        u32 val;
 
-       spin_lock(&dev_priv->hw_lock);
-       outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT);
-       val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT);
-       spin_unlock(&dev_priv->hw_lock);
+       if (vmw_is_svga_v3(dev_priv)) {
+               val = ioread32(dev_priv->rmmio + offset);
+       } else {
+               spin_lock(&dev_priv->hw_lock);
+               outl(offset, dev_priv->io_start + SVGA_INDEX_PORT);
+               val = inl(dev_priv->io_start + SVGA_VALUE_PORT);
+               spin_unlock(&dev_priv->hw_lock);
+       }
 
        return val;
 }
@@ -932,19 +949,14 @@ extern int vmw_present_ioctl(struct drm_device *dev, void *data,
                             struct drm_file *file_priv);
 extern int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
                                      struct drm_file *file_priv);
-extern __poll_t vmw_fops_poll(struct file *filp,
-                                 struct poll_table_struct *wait);
-extern ssize_t vmw_fops_read(struct file *filp, char __user *buffer,
-                            size_t count, loff_t *offset);
 
 /**
  * Fifo utilities - vmwgfx_fifo.c
  */
 
-extern int vmw_fifo_init(struct vmw_private *dev_priv,
-                        struct vmw_fifo_state *fifo);
-extern void vmw_fifo_release(struct vmw_private *dev_priv,
-                            struct vmw_fifo_state *fifo);
+extern struct vmw_fifo_state *vmw_fifo_create(struct vmw_private *dev_priv);
+extern void vmw_fifo_destroy(struct vmw_private *dev_priv);
+extern bool vmw_cmd_supported(struct vmw_private *vmw);
 extern void *
 vmw_cmd_ctx_reserve(struct vmw_private *dev_priv, uint32_t bytes, int ctx_id);
 extern void vmw_cmd_commit(struct vmw_private *dev_priv, uint32_t bytes);
@@ -970,6 +982,31 @@ extern int vmw_cmd_flush(struct vmw_private *dev_priv,
 #define VMW_CMD_RESERVE(__priv, __bytes)                                     \
        VMW_CMD_CTX_RESERVE(__priv, __bytes, SVGA3D_INVALID_ID)
 
+
+/**
+ * vmw_fifo_caps - Returns the capabilities of the FIFO command
+ * queue or 0 if fifo memory isn't present.
+ * @dev_priv: The device private context
+ */
+static inline uint32_t vmw_fifo_caps(const struct vmw_private *dev_priv)
+{
+       if (!dev_priv->fifo_mem || !dev_priv->fifo)
+               return 0;
+       return dev_priv->fifo->capabilities;
+}
+
+
+/**
+ * vmw_is_cursor_bypass3_enabled - Returns TRUE iff Cursor Bypass 3
+ * is enabled in the FIFO.
+ * @dev_priv: The device private context
+ */
+static inline bool
+vmw_is_cursor_bypass3_enabled(const struct vmw_private *dev_priv)
+{
+       return (vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_CURSOR_BYPASS_3) != 0;
+}
+
 /**
  * TTM glue - vmwgfx_ttm_glue.c
  */
@@ -1079,9 +1116,6 @@ bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd);
  * IRQs and wating - vmwgfx_irq.c
  */
 
-extern int vmw_wait_seqno(struct vmw_private *dev_priv, bool lazy,
-                         uint32_t seqno, bool interruptible,
-                         unsigned long timeout);
 extern int vmw_irq_install(struct drm_device *dev, int irq);
 extern void vmw_irq_uninstall(struct drm_device *dev);
 extern bool vmw_seqno_passed(struct vmw_private *dev_priv,
@@ -1092,8 +1126,7 @@ extern int vmw_fallback_wait(struct vmw_private *dev_priv,
                             uint32_t seqno,
                             bool interruptible,
                             unsigned long timeout);
-extern void vmw_update_seqno(struct vmw_private *dev_priv,
-                               struct vmw_fifo_state *fifo_state);
+extern void vmw_update_seqno(struct vmw_private *dev_priv);
 extern void vmw_seqno_waiter_add(struct vmw_private *dev_priv);
 extern void vmw_seqno_waiter_remove(struct vmw_private *dev_priv);
 extern void vmw_goal_waiter_add(struct vmw_private *dev_priv);
@@ -1572,6 +1605,7 @@ static inline void vmw_fifo_resource_dec(struct vmw_private *dev_priv)
  */
 static inline u32 vmw_fifo_mem_read(struct vmw_private *vmw, uint32 fifo_reg)
 {
+       BUG_ON(vmw_is_svga_v3(vmw));
        return READ_ONCE(*(vmw->fifo_mem + fifo_reg));
 }
 
@@ -1586,6 +1620,44 @@ static inline u32 vmw_fifo_mem_read(struct vmw_private *vmw, uint32 fifo_reg)
 static inline void vmw_fifo_mem_write(struct vmw_private *vmw, u32 fifo_reg,
                                      u32 value)
 {
+       BUG_ON(vmw_is_svga_v3(vmw));
        WRITE_ONCE(*(vmw->fifo_mem + fifo_reg), value);
 }
+
+static inline u32 vmw_fence_read(struct vmw_private *dev_priv)
+{
+       u32 fence;
+       if (vmw_is_svga_v3(dev_priv))
+               fence = vmw_read(dev_priv, SVGA_REG_FENCE);
+       else
+               fence = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_FENCE);
+       return fence;
+}
+
+static inline void vmw_fence_write(struct vmw_private *dev_priv,
+                                 u32 fence)
+{
+       BUG_ON(vmw_is_svga_v3(dev_priv));
+       vmw_fifo_mem_write(dev_priv, SVGA_FIFO_FENCE, fence);
+}
+
+static inline u32 vmw_irq_status_read(struct vmw_private *vmw)
+{
+       u32 status;
+       if (vmw_is_svga_v3(vmw))
+               status = vmw_read(vmw, SVGA_REG_IRQ_STATUS);
+       else
+               status = inl(vmw->io_start + SVGA_IRQSTATUS_PORT);
+       return status;
+}
+
+static inline void vmw_irq_status_write(struct vmw_private *vmw,
+                                       uint32 status)
+{
+       if (vmw_is_svga_v3(vmw))
+               vmw_write(vmw, SVGA_REG_IRQ_STATUS, status);
+       else
+               outl(status, vmw->io_start + SVGA_IRQSTATUS_PORT);
+}
+
 #endif
index 3ad0765..32a84df 100644 (file)
@@ -711,7 +711,7 @@ vmw_cmd_res_check(struct vmw_private *dev_priv,
 }
 
 /**
- * vmw_rebind_dx_query - Rebind DX query associated with the context
+ * vmw_rebind_all_dx_query - Rebind DX query associated with the context
  *
  * @ctx_res: context the query belongs to
  *
@@ -1140,7 +1140,7 @@ static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv,
 }
 
 /**
- * vmw_translate_mob_pointer - Prepare to translate a user-space buffer handle
+ * vmw_translate_mob_ptr - Prepare to translate a user-space buffer handle
  * to a MOB id.
  *
  * @dev_priv: Pointer to a device private structure.
@@ -1195,7 +1195,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
 }
 
 /**
- * vmw_translate_guest_pointer - Prepare to translate a user-space buffer handle
+ * vmw_translate_guest_ptr - Prepare to translate a user-space buffer handle
  * to a valid SVGAGuestPtr
  *
  * @dev_priv: Pointer to a device private structure.
@@ -2308,7 +2308,7 @@ static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv,
 }
 
 /**
- * vmw_cmd_dx_ia_set_vertex_buffers - Validate
+ * vmw_cmd_dx_set_index_buffer - Validate
  * SVGA_3D_CMD_DX_IA_SET_INDEX_BUFFER command.
  *
  * @dev_priv: Pointer to a device private struct.
@@ -2347,7 +2347,7 @@ static int vmw_cmd_dx_set_index_buffer(struct vmw_private *dev_priv,
 }
 
 /**
- * vmw_cmd_dx_set_rendertarget - Validate SVGA_3D_CMD_DX_SET_RENDERTARGETS
+ * vmw_cmd_dx_set_rendertargets - Validate SVGA_3D_CMD_DX_SET_RENDERTARGETS
  * command
  *
  * @dev_priv: Pointer to a device private struct.
@@ -2402,7 +2402,7 @@ static int vmw_cmd_dx_clear_rendertarget_view(struct vmw_private *dev_priv,
 }
 
 /**
- * vmw_cmd_dx_clear_rendertarget_view - Validate
+ * vmw_cmd_dx_clear_depthstencil_view - Validate
  * SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW command
  *
  * @dev_priv: Pointer to a device private struct.
@@ -3841,7 +3841,7 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
 
                fence_rep.handle = fence_handle;
                fence_rep.seqno = fence->base.seqno;
-               vmw_update_seqno(dev_priv, &dev_priv->fifo);
+               vmw_update_seqno(dev_priv);
                fence_rep.passed_seqno = dev_priv->last_read_seqno;
        }
 
index 23523eb..9fe1232 100644 (file)
@@ -139,12 +139,10 @@ static bool vmw_fence_enable_signaling(struct dma_fence *f)
        struct vmw_fence_manager *fman = fman_from_fence(fence);
        struct vmw_private *dev_priv = fman->dev_priv;
 
-       u32 seqno = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_FENCE);
+       u32 seqno = vmw_fence_read(dev_priv);
        if (seqno - fence->base.seqno < VMW_FENCE_WRAP)
                return false;
 
-       vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
-
        return true;
 }
 
@@ -177,7 +175,6 @@ static long vmw_fence_wait(struct dma_fence *f, bool intr, signed long timeout)
        if (likely(vmw_fence_obj_signaled(fence)))
                return timeout;
 
-       vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
        vmw_seqno_waiter_add(dev_priv);
 
        spin_lock(f->lock);
@@ -464,7 +461,7 @@ static void __vmw_fences_update(struct vmw_fence_manager *fman)
        bool needs_rerun;
        uint32_t seqno, new_seqno;
 
-       seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE);
+       seqno = vmw_fence_read(fman->dev_priv);
 rerun:
        list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) {
                if (seqno - fence->base.seqno < VMW_FENCE_WRAP) {
@@ -486,7 +483,7 @@ rerun:
 
        needs_rerun = vmw_fence_goal_new_locked(fman, seqno);
        if (unlikely(needs_rerun)) {
-               new_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE);
+               new_seqno = vmw_fence_read(fman->dev_priv);
                if (new_seqno != seqno) {
                        seqno = new_seqno;
                        goto rerun;
@@ -529,13 +526,6 @@ int vmw_fence_obj_wait(struct vmw_fence_obj *fence, bool lazy,
                return ret;
 }
 
-void vmw_fence_obj_flush(struct vmw_fence_obj *fence)
-{
-       struct vmw_private *dev_priv = fman_from_fence(fence)->dev_priv;
-
-       vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
-}
-
 static void vmw_fence_destroy(struct vmw_fence_obj *fence)
 {
        dma_fence_free(&fence->base);
@@ -992,7 +982,7 @@ static void vmw_fence_obj_add_action(struct vmw_fence_obj *fence,
 }
 
 /**
- * vmw_event_fence_action_create - Post an event for sending when a fence
+ * vmw_event_fence_action_queue - Post an event for sending when a fence
  * object seqno has passed.
  *
  * @file_priv: The file connection on which the event should be posted.
index 50e9fdd..079ab4f 100644 (file)
@@ -94,8 +94,6 @@ extern int vmw_fence_obj_wait(struct vmw_fence_obj *fence,
                              bool lazy,
                              bool interruptible, unsigned long timeout);
 
-extern void vmw_fence_obj_flush(struct vmw_fence_obj *fence);
-
 extern int vmw_fence_create(struct vmw_fence_manager *fman,
                            uint32_t seqno,
                            struct vmw_fence_obj **p_fence);
index 6763d06..4fdacf9 100644 (file)
@@ -60,15 +60,13 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
                param->value = dev_priv->capabilities2;
                break;
        case DRM_VMW_PARAM_FIFO_CAPS:
-               param->value = dev_priv->fifo.capabilities;
+               param->value = vmw_fifo_caps(dev_priv);
                break;
        case DRM_VMW_PARAM_MAX_FB_SIZE:
                param->value = dev_priv->prim_bb_mem;
                break;
        case DRM_VMW_PARAM_FIFO_HW_VERSION:
        {
-               const struct vmw_fifo_state *fifo = &dev_priv->fifo;
-
                if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS)) {
                        param->value = SVGA3D_HWVERSION_WS8_B1;
                        break;
@@ -76,7 +74,7 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data,
 
                param->value =
                        vmw_fifo_mem_read(dev_priv,
-                                         ((fifo->capabilities &
+                                         ((vmw_fifo_caps(dev_priv) &
                                            SVGA_FIFO_CAP_3D_HWVERSION_REVISED) ?
                                                   SVGA_FIFO_3D_HWVERSION_REVISED :
                                                   SVGA_FIFO_3D_HWVERSION));
@@ -398,46 +396,3 @@ out_no_copy:
 out_clips:
        return ret;
 }
-
-
-/**
- * vmw_fops_poll - wrapper around the drm_poll function
- *
- * @filp: See the linux fops poll documentation.
- * @wait: See the linux fops poll documentation.
- *
- * Wrapper around the drm_poll function that makes sure the device is
- * processing the fifo if drm_poll decides to wait.
- */
-__poll_t vmw_fops_poll(struct file *filp, struct poll_table_struct *wait)
-{
-       struct drm_file *file_priv = filp->private_data;
-       struct vmw_private *dev_priv =
-               vmw_priv(file_priv->minor->dev);
-
-       vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
-       return drm_poll(filp, wait);
-}
-
-
-/**
- * vmw_fops_read - wrapper around the drm_read function
- *
- * @filp: See the linux fops read documentation.
- * @buffer: See the linux fops read documentation.
- * @count: See the linux fops read documentation.
- * @offset: See the linux fops read documentation.
- *
- * Wrapper around the drm_read function that makes sure the device is
- * processing the fifo if drm_read decides to wait.
- */
-ssize_t vmw_fops_read(struct file *filp, char __user *buffer,
-                     size_t count, loff_t *offset)
-{
-       struct drm_file *file_priv = filp->private_data;
-       struct vmw_private *dev_priv =
-               vmw_priv(file_priv->minor->dev);
-
-       vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
-       return drm_read(filp, buffer, count, offset);
-}
index 6c2a569..b9a9b7d 100644 (file)
@@ -65,7 +65,7 @@ static irqreturn_t vmw_thread_fn(int irq, void *arg)
 }
 
 /**
- * vmw_irq_handler irq handler
+ * vmw_irq_handler: irq handler
  *
  * @irq: irq number
  * @arg: Closure argument. Pointer to a struct drm_device cast to void *
@@ -82,11 +82,11 @@ static irqreturn_t vmw_irq_handler(int irq, void *arg)
        uint32_t status, masked_status;
        irqreturn_t ret = IRQ_HANDLED;
 
-       status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+       status = vmw_irq_status_read(dev_priv);
        masked_status = status & READ_ONCE(dev_priv->irq_mask);
 
        if (likely(status))
-               outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+               vmw_irq_status_write(dev_priv, status);
 
        if (!status)
                return IRQ_NONE;
@@ -114,10 +114,9 @@ static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno)
        return (vmw_read(dev_priv, SVGA_REG_BUSY) == 0);
 }
 
-void vmw_update_seqno(struct vmw_private *dev_priv,
-                        struct vmw_fifo_state *fifo_state)
+void vmw_update_seqno(struct vmw_private *dev_priv)
 {
-       uint32_t seqno = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_FENCE);
+       uint32_t seqno = vmw_fence_read(dev_priv);
 
        if (dev_priv->last_read_seqno != seqno) {
                dev_priv->last_read_seqno = seqno;
@@ -128,18 +127,16 @@ void vmw_update_seqno(struct vmw_private *dev_priv,
 bool vmw_seqno_passed(struct vmw_private *dev_priv,
                         uint32_t seqno)
 {
-       struct vmw_fifo_state *fifo_state;
        bool ret;
 
        if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP))
                return true;
 
-       fifo_state = &dev_priv->fifo;
-       vmw_update_seqno(dev_priv, fifo_state);
+       vmw_update_seqno(dev_priv);
        if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP))
                return true;
 
-       if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE) &&
+       if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE) &&
            vmw_fifo_idle(dev_priv, seqno))
                return true;
 
@@ -161,7 +158,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv,
                      bool interruptible,
                      unsigned long timeout)
 {
-       struct vmw_fifo_state *fifo_state = &dev_priv->fifo;
+       struct vmw_fifo_state *fifo_state = dev_priv->fifo;
 
        uint32_t count = 0;
        uint32_t signal_seq;
@@ -221,7 +218,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv,
        }
        finish_wait(&dev_priv->fence_queue, &__wait);
        if (ret == 0 && fifo_idle)
-               vmw_fifo_mem_write(dev_priv, SVGA_FIFO_FENCE, signal_seq);
+               vmw_fence_write(dev_priv, signal_seq);
 
        wake_up_all(&dev_priv->fence_queue);
 out_err:
@@ -236,7 +233,7 @@ void vmw_generic_waiter_add(struct vmw_private *dev_priv,
 {
        spin_lock_bh(&dev_priv->waiter_lock);
        if ((*waiter_count)++ == 0) {
-               outl(flag, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+               vmw_irq_status_write(dev_priv, flag);
                dev_priv->irq_mask |= flag;
                vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask);
        }
@@ -278,59 +275,13 @@ void vmw_goal_waiter_remove(struct vmw_private *dev_priv)
                                  &dev_priv->goal_queue_waiters);
 }
 
-int vmw_wait_seqno(struct vmw_private *dev_priv,
-                     bool lazy, uint32_t seqno,
-                     bool interruptible, unsigned long timeout)
-{
-       long ret;
-       struct vmw_fifo_state *fifo = &dev_priv->fifo;
-
-       if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP))
-               return 0;
-
-       if (likely(vmw_seqno_passed(dev_priv, seqno)))
-               return 0;
-
-       vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC);
-
-       if (!(fifo->capabilities & SVGA_FIFO_CAP_FENCE))
-               return vmw_fallback_wait(dev_priv, lazy, true, seqno,
-                                        interruptible, timeout);
-
-       if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK))
-               return vmw_fallback_wait(dev_priv, lazy, false, seqno,
-                                        interruptible, timeout);
-
-       vmw_seqno_waiter_add(dev_priv);
-
-       if (interruptible)
-               ret = wait_event_interruptible_timeout
-                   (dev_priv->fence_queue,
-                    vmw_seqno_passed(dev_priv, seqno),
-                    timeout);
-       else
-               ret = wait_event_timeout
-                   (dev_priv->fence_queue,
-                    vmw_seqno_passed(dev_priv, seqno),
-                    timeout);
-
-       vmw_seqno_waiter_remove(dev_priv);
-
-       if (unlikely(ret == 0))
-               ret = -EBUSY;
-       else if (likely(ret > 0))
-               ret = 0;
-
-       return ret;
-}
-
 static void vmw_irq_preinstall(struct drm_device *dev)
 {
        struct vmw_private *dev_priv = vmw_priv(dev);
        uint32_t status;
 
-       status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
-       outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+       status = vmw_irq_status_read(dev_priv);
+       vmw_irq_status_write(dev_priv, status);
 }
 
 void vmw_irq_uninstall(struct drm_device *dev)
@@ -346,8 +297,8 @@ void vmw_irq_uninstall(struct drm_device *dev)
 
        vmw_write(dev_priv, SVGA_REG_IRQMASK, 0);
 
-       status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
-       outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT);
+       status = vmw_irq_status_read(dev_priv);
+       vmw_irq_status_write(dev_priv, status);
 
        dev->irq_enabled = false;
        free_irq(dev->irq, dev);
index 67f693a..220f9fd 100644 (file)
 
 void vmw_du_cleanup(struct vmw_display_unit *du)
 {
+       struct vmw_private *dev_priv = vmw_priv(du->primary.dev);
        drm_plane_cleanup(&du->primary);
-       drm_plane_cleanup(&du->cursor);
+       if (vmw_cmd_supported(dev_priv))
+               drm_plane_cleanup(&du->cursor);
 
        drm_connector_unregister(&du->connector);
        drm_crtc_cleanup(&du->crtc);
@@ -128,11 +130,17 @@ static void vmw_cursor_update_position(struct vmw_private *dev_priv,
        uint32_t count;
 
        spin_lock(&dev_priv->cursor_lock);
-       vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_ON, show ? 1 : 0);
-       vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_X, x);
-       vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_Y, y);
-       count = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_CURSOR_COUNT);
-       vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_COUNT, ++count);
+       if (vmw_is_cursor_bypass3_enabled(dev_priv)) {
+               vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_ON, show ? 1 : 0);
+               vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_X, x);
+               vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_Y, y);
+               count = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_CURSOR_COUNT);
+               vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_COUNT, ++count);
+       } else {
+               vmw_write(dev_priv, SVGA_REG_CURSOR_X, x);
+               vmw_write(dev_priv, SVGA_REG_CURSOR_Y, y);
+               vmw_write(dev_priv, SVGA_REG_CURSOR_ON, show ? 1 : 0);
+       }
        spin_unlock(&dev_priv->cursor_lock);
 }
 
@@ -289,7 +297,7 @@ void vmw_du_primary_plane_destroy(struct drm_plane *plane)
 
 
 /**
- * vmw_du_vps_unpin_surf - unpins resource associated with a framebuffer surface
+ * vmw_du_plane_unpin_surf - unpins resource associated with a framebuffer surface
  *
  * @vps: plane state associated with the display surface
  * @unreference: true if we also want to unreference the display.
@@ -474,7 +482,7 @@ int vmw_du_primary_plane_atomic_check(struct drm_plane *plane,
  * vmw_du_cursor_plane_atomic_check - check if the new state is okay
  *
  * @plane: cursor plane
- * @new_state: info on the new plane state
+ * @state: info on the new plane state
  *
  * This is a chance to fail if the new cursor state does not fit
  * our requirements.
@@ -1045,7 +1053,8 @@ static int vmw_framebuffer_bo_dirty_ext(struct drm_framebuffer *framebuffer,
 {
        struct vmw_private *dev_priv = vmw_priv(framebuffer->dev);
 
-       if (dev_priv->active_display_unit == vmw_du_legacy)
+       if (dev_priv->active_display_unit == vmw_du_legacy &&
+           vmw_cmd_supported(dev_priv))
                return vmw_framebuffer_bo_dirty(framebuffer, file_priv, flags,
                                                color, clips, num_clips);
 
@@ -2633,7 +2642,7 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
 }
 
 /**
- * vmw_kms_create_implicit_placement_proparty - Set up the implicit placement
+ * vmw_kms_create_implicit_placement_property - Set up the implicit placement
  * property.
  *
  * @dev_priv: Pointer to a device private struct.
index 87e0b30..d85c7ea 100644 (file)
@@ -404,19 +404,24 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
 
        drm_plane_helper_add(primary, &vmw_ldu_primary_plane_helper_funcs);
 
-       /* Initialize cursor plane */
-       ret = drm_universal_plane_init(dev, &ldu->base.cursor,
-                       0, &vmw_ldu_cursor_funcs,
-                       vmw_cursor_plane_formats,
-                       ARRAY_SIZE(vmw_cursor_plane_formats),
-                       NULL, DRM_PLANE_TYPE_CURSOR, NULL);
-       if (ret) {
-               DRM_ERROR("Failed to initialize cursor plane");
-               drm_plane_cleanup(&ldu->base.primary);
-               goto err_free;
-       }
+       /*
+        * We're going to be using traces and software cursors
+        */
+       if (vmw_cmd_supported(dev_priv)) {
+               /* Initialize cursor plane */
+               ret = drm_universal_plane_init(dev, &ldu->base.cursor,
+                                              0, &vmw_ldu_cursor_funcs,
+                                              vmw_cursor_plane_formats,
+                                              ARRAY_SIZE(vmw_cursor_plane_formats),
+                                              NULL, DRM_PLANE_TYPE_CURSOR, NULL);
+               if (ret) {
+                       DRM_ERROR("Failed to initialize cursor plane");
+                       drm_plane_cleanup(&ldu->base.primary);
+                       goto err_free;
+               }
 
-       drm_plane_helper_add(cursor, &vmw_ldu_cursor_plane_helper_funcs);
+               drm_plane_helper_add(cursor, &vmw_ldu_cursor_plane_helper_funcs);
+       }
 
        ret = drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
                                 DRM_MODE_CONNECTOR_VIRTUAL);
@@ -445,9 +450,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
                goto err_free_encoder;
        }
 
-       ret = drm_crtc_init_with_planes(dev, crtc, &ldu->base.primary,
-                                       &ldu->base.cursor,
-                                       &vmw_legacy_crtc_funcs, NULL);
+       ret = drm_crtc_init_with_planes(
+                     dev, crtc, &ldu->base.primary,
+                     vmw_cmd_supported(dev_priv) ? &ldu->base.cursor : NULL,
+                     &vmw_legacy_crtc_funcs, NULL);
        if (ret) {
                DRM_ERROR("Failed to initialize CRTC\n");
                goto err_free_unregister;
index ac4a9b7..54c5d16 100644 (file)
@@ -421,7 +421,7 @@ int vmw_overlay_pause_all(struct vmw_private *dev_priv)
 static bool vmw_overlay_available(const struct vmw_private *dev_priv)
 {
        return (dev_priv->overlay_priv != NULL &&
-               ((dev_priv->fifo.capabilities & VMW_OVERLAY_CAP_MASK) ==
+               ((vmw_fifo_caps(dev_priv) & VMW_OVERLAY_CAP_MASK) ==
                 VMW_OVERLAY_CAP_MASK));
 }
 
index e99f6cd..cf585df 100644 (file)
 
 #include <linux/types.h>
 
-#define VMWGFX_INDEX_PORT     0x0
-#define VMWGFX_VALUE_PORT     0x1
-#define VMWGFX_IRQSTATUS_PORT 0x8
-
 struct svga_guest_mem_descriptor {
        u32 ppn;
        u32 num_pages;
index d5da28b..62ea920 100644 (file)
@@ -280,7 +280,7 @@ out_bad_resource:
 }
 
 /**
- * vmw_user_resource_lookup_handle - lookup a struct resource from a
+ * vmw_user_resource_noref_lookup_handle - lookup a struct resource from a
  * TTM user-space handle and perform basic type checks
  *
  * @dev_priv:     Pointer to a device private struct
@@ -1075,7 +1075,7 @@ enum vmw_res_type vmw_res_type(const struct vmw_resource *res)
 }
 
 /**
- * vmw_resource_update_dirty - Update a resource's dirty tracker with a
+ * vmw_resource_dirty_update - Update a resource's dirty tracker with a
  * sequential range of touched backing store memory.
  * @res: The resource.
  * @start: The first page touched.
index 9bc9a07..145430d 100644 (file)
@@ -1222,7 +1222,7 @@ static void vmw_sou_bo_clip(struct vmw_kms_dirty *dirty)
 }
 
 /**
- * vmw_kms_do_bo_dirty - Dirty part of a buffer-object backed framebuffer
+ * vmw_kms_sou_do_bo_dirty - Dirty part of a buffer-object backed framebuffer
  *
  * @dev_priv: Pointer to the device private structure.
  * @framebuffer: Pointer to the buffer-object backed framebuffer.
index a0e49dc..c3a8d6e 100644 (file)
@@ -90,7 +90,7 @@ static const struct vmw_res_func vmw_view_func = {
 };
 
 /**
- * struct vmw_view - view define command body stub
+ * struct vmw_view_define - view define command body stub
  *
  * @view_id: The device id of the view being defined
  * @sid: The surface id of the view being defined
index 7b11f02..9e236f9 100644 (file)
@@ -742,7 +742,7 @@ out_unref:
 }
 
 /**
- * vmw_stdu_surface_clip - Callback to encode a surface copy command cliprect
+ * vmw_kms_stdu_surface_clip - Callback to encode a surface copy command cliprect
  *
  * @dirty: The closure structure.
  *
@@ -780,7 +780,7 @@ static void vmw_kms_stdu_surface_clip(struct vmw_kms_dirty *dirty)
 }
 
 /**
- * vmw_stdu_surface_fifo_commit - Callback to fill in and submit a surface
+ * vmw_kms_stdu_surface_fifo_commit - Callback to fill in and submit a surface
  * copy command.
  *
  * @dirty: The closure structure.
@@ -1571,7 +1571,7 @@ static int vmw_stdu_plane_update_surface(struct vmw_private *dev_priv,
 /**
  * vmw_stdu_primary_plane_atomic_update - formally switches STDU to new plane
  * @plane: display plane
- * @old_state: Only used to get crtc info
+ * @state: Only used to get crtc info
  *
  * Formally update stdu->display_srf to the new plane, and bind the new
  * plane STDU.  This function is called during the commit phase when
index 4e08cd7..8ead065 100644 (file)
@@ -680,7 +680,7 @@ static void vmw_user_surface_free(struct vmw_resource *res)
 }
 
 /**
- * vmw_user_surface_free - User visible surface TTM base object destructor
+ * vmw_user_surface_base_release - User visible surface TTM base object destructor
  *
  * @p_base:         Pointer to a pointer to a TTM base object
  *                  embedded in a struct vmw_user_surface.
@@ -702,7 +702,7 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
 }
 
 /**
- * vmw_user_surface_destroy_ioctl - Ioctl function implementing
+ * vmw_surface_destroy_ioctl - Ioctl function implementing
  *                                  the user surface destroy functionality.
  *
  * @dev:            Pointer to a struct drm_device.
@@ -719,7 +719,7 @@ int vmw_surface_destroy_ioctl(struct drm_device *dev, void *data,
 }
 
 /**
- * vmw_user_surface_define_ioctl - Ioctl function implementing
+ * vmw_surface_define_ioctl - Ioctl function implementing
  *                                  the user surface define functionality.
  *
  * @dev:            Pointer to a struct drm_device.
@@ -1001,7 +1001,7 @@ out_no_lookup:
 }
 
 /**
- * vmw_user_surface_define_ioctl - Ioctl function implementing
+ * vmw_surface_reference_ioctl - Ioctl function implementing
  *                                  the user surface reference functionality.
  *
  * @dev:            Pointer to a struct drm_device.
@@ -1055,7 +1055,7 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
 }
 
 /**
- * vmw_surface_define_encode - Encode a surface_define command.
+ * vmw_gb_surface_create - Encode a surface_define command.
  *
  * @res:        Pointer to a struct vmw_resource embedded in a struct
  *              vmw_surface.
index 2dc031f..7bfe83c 100644 (file)
@@ -200,7 +200,8 @@ struct vmw_ttm_tt {
 const size_t vmw_tt_size = sizeof(struct vmw_ttm_tt);
 
 /**
- * Helper functions to advance a struct vmw_piter iterator.
+ * __vmw_piter_non_sg_next: Helper functions to advance
+ * a struct vmw_piter iterator.
  *
  * @viter: Pointer to the iterator.
  *
@@ -222,7 +223,8 @@ static bool __vmw_piter_sg_next(struct vmw_piter *viter)
 
 
 /**
- * Helper functions to return a pointer to the current page.
+ * __vmw_piter_non_sg_page: Helper functions to return a pointer
+ * to the current page.
  *
  * @viter: Pointer to the iterator
  *
@@ -236,7 +238,8 @@ static struct page *__vmw_piter_non_sg_page(struct vmw_piter *viter)
 }
 
 /**
- * Helper functions to return the DMA address of the current page.
+ * __vmw_piter_phys_addr: Helper functions to return the DMA
+ * address of the current page.
  *
  * @viter: Pointer to the iterator
  *
index f483713..8338b1d 100644 (file)
@@ -809,7 +809,7 @@ void vmw_validation_revert(struct vmw_validation_context *ctx)
 }
 
 /**
- * vmw_validation_cone - Commit validation actions after command submission
+ * vmw_validation_done - Commit validation actions after command submission
  * success.
  * @ctx: The validation context.
  * @fence: Fence with which to fence all buffer objects taking part in the