summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vmwgfx
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2014-01-15 10:04:07 +0100
committerThomas Hellstrom <thellstrom@vmware.com>2014-01-17 07:52:40 +0100
commitf2a0dcb1aa23eea8f186b4773a653e61d509b17a (patch)
tree78da88ecb806b272086a84e8d26b4f4e503a19a6 /drivers/gpu/drm/vmwgfx
parentb360a3cecd3a2e14e56798b570007d4763f21b74 (diff)
drm/vmwgfx: Implement 64-bit Otable- and MOB binding v2
Adds the relevant commands to the device interface header and implements 64-bit binding for 64 bit VMs. v2: Uppercase command IDs, Correctly use also 64 bit page tables. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
-rw-r--r--drivers/gpu/drm/vmwgfx/svga3d_reg.h54
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_mob.c70
3 files changed, 101 insertions, 25 deletions
diff --git a/drivers/gpu/drm/vmwgfx/svga3d_reg.h b/drivers/gpu/drm/vmwgfx/svga3d_reg.h
index fce351b7d37c..b1e5d2c48339 100644
--- a/drivers/gpu/drm/vmwgfx/svga3d_reg.h
+++ b/drivers/gpu/drm/vmwgfx/svga3d_reg.h
@@ -35,6 +35,7 @@
#include "svga_reg.h"
typedef uint32 PPN;
+typedef __le64 PPN64;
/*
* 3D Hardware Version
@@ -1200,7 +1201,7 @@ typedef enum {
#define SVGA_3D_CMD_DESTROY_GB_SHADER 1113
#define SVGA_3D_CMD_BIND_GB_SHADER 1114
-#define SVGA_3D_CMD_BIND_SHADERCONSTS 1115
+#define SVGA_3D_CMD_SET_OTABLE_BASE64 1115
#define SVGA_3D_CMD_BEGIN_GB_QUERY 1116
#define SVGA_3D_CMD_END_GB_QUERY 1117
@@ -1223,7 +1224,10 @@ typedef enum {
#define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130
-#define SVGA_3D_CMD_MAX 1131
+#define SVGA_3D_CMD_DEFINE_GB_MOB64 1135
+#define SVGA_3D_CMD_REDEFINE_GB_MOB64 1136
+
+#define SVGA_3D_CMD_MAX 1142
#define SVGA_3D_CMD_FUTURE_MAX 3000
/*
@@ -1927,6 +1931,9 @@ typedef enum SVGAMobFormat {
SVGA3D_MOBFMT_PTDEPTH_1 = 1,
SVGA3D_MOBFMT_PTDEPTH_2 = 2,
SVGA3D_MOBFMT_RANGE = 3,
+ SVGA3D_MOBFMT_PTDEPTH64_0 = 4,
+ SVGA3D_MOBFMT_PTDEPTH64_1 = 5,
+ SVGA3D_MOBFMT_PTDEPTH64_2 = 6,
SVGA3D_MOBFMT_MAX,
} SVGAMobFormat;
@@ -1971,6 +1978,15 @@ struct {
typedef
struct {
SVGAOTableType type;
+ PPN64 baseAddress;
+ uint32 sizeInBytes;
+ uint32 validSizeInBytes;
+ SVGAMobFormat ptDepth;
+} SVGA3dCmdSetOTableBase64; /* SVGA_3D_CMD_SET_OTABLE_BASE64 */
+
+typedef
+struct {
+ SVGAOTableType type;
} SVGA3dCmdReadbackOTable; /* SVGA_3D_CMD_READBACK_OTABLE */
/*
@@ -2008,6 +2024,32 @@ struct SVGA3dCmdRedefineGBMob {
} SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */
/*
+ * Define a memory object (Mob) in the OTable with a PPN64 base.
+ */
+
+typedef
+struct SVGA3dCmdDefineGBMob64 {
+ SVGAMobId mobid;
+ SVGAMobFormat ptDepth;
+ PPN64 base;
+ uint32 sizeInBytes;
+}
+SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */
+
+/*
+ * Redefine an object in the OTable with PPN64 base.
+ */
+
+typedef
+struct SVGA3dCmdRedefineGBMob64 {
+ SVGAMobId mobid;
+ SVGAMobFormat ptDepth;
+ PPN64 base;
+ uint32 sizeInBytes;
+}
+SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */
+
+/*
* Notification that the page tables have been modified.
*/
@@ -2243,14 +2285,6 @@ typedef struct SVGA3dCmdDestroyGBShader {
uint32 shid;
} SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */
-
-typedef struct SVGA3dCmdBindGBShaderConsts {
- uint32 cid;
- SVGA3dShaderType shaderType;
- SVGA3dShaderConstType shaderConstType;
- uint32 sid;
-} SVGA3dCmdBindGBShaderConsts; /* SVGA_3D_CMD_BIND_SHADERCONSTS */
-
typedef
struct {
uint32 cid;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index b924fd6e6edd..7a5f1eb55c5a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -1730,7 +1730,7 @@ static const struct vmw_cmd_entry const vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SHADER, &vmw_cmd_invalid,
false, false, true),
- VMW_CMD_DEF(SVGA_3D_CMD_BIND_SHADERCONSTS, &vmw_cmd_invalid,
+ VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE64, &vmw_cmd_invalid,
false, false, false),
VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_GB_QUERY, &vmw_cmd_begin_gb_query,
true, false, true),
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
index 388b64d9752f..ad29651a4302 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
@@ -33,13 +33,25 @@
#define VMW_OTABLE_SETUP_SUB ((VMWGFX_ENABLE_SCREEN_TARGET_OTABLE) ? 0 : 1)
-/*
- * Currently the MOB interface does not support 64-bit page frame numbers.
- * This might change in the future to be similar to the GMR2 interface
- * when virtual machines support memory beyond 16TB.
- */
-
+#ifdef CONFIG_64BIT
+#define VMW_PPN_SIZE 8
+#define vmw_cmd_set_otable_base SVGA3dCmdSetOTableBase64
+#define VMW_ID_SET_OTABLE_BASE SVGA_3D_CMD_SET_OTABLE_BASE64
+#define vmw_cmd_define_gb_mob SVGA3dCmdDefineGBMob64
+#define VMW_ID_DEFINE_GB_MOB SVGA_3D_CMD_DEFINE_GB_MOB64
+#define VMW_MOBFMT_PTDEPTH_0 SVGA3D_MOBFMT_PTDEPTH64_0
+#define VMW_MOBFMT_PTDEPTH_1 SVGA3D_MOBFMT_PTDEPTH64_1
+#define VMW_MOBFMT_PTDEPTH_2 SVGA3D_MOBFMT_PTDEPTH64_2
+#else
#define VMW_PPN_SIZE 4
+#define vmw_cmd_set_otable_base SVGA3dCmdSetOTableBase
+#define VMW_ID_SET_OTABLE_BASE SVGA_3D_CMD_SET_OTABLE_BASE
+#define vmw_cmd_define_gb_mob SVGA3dCmdDefineGBMob
+#define VMW_ID_DEFINE_GB_MOB SVGA_3D_CMD_DEFINE_GB_MOB
+#define VMW_MOBFMT_PTDEPTH_0 SVGA3D_MOBFMT_PTDEPTH_0
+#define VMW_MOBFMT_PTDEPTH_1 SVGA3D_MOBFMT_PTDEPTH_1
+#define VMW_MOBFMT_PTDEPTH_2 SVGA3D_MOBFMT_PTDEPTH_2
+#endif
/*
* struct vmw_mob - Structure containing page table and metadata for a
@@ -93,7 +105,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
{
struct {
SVGA3dCmdHeader header;
- SVGA3dCmdSetOTableBase body;
+ vmw_cmd_set_otable_base body;
} *cmd;
struct vmw_mob *mob;
const struct vmw_sg_table *vsgt;
@@ -113,7 +125,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
}
if (otable->size <= PAGE_SIZE) {
- mob->pt_level = SVGA3D_MOBFMT_PTDEPTH_0;
+ mob->pt_level = VMW_MOBFMT_PTDEPTH_0;
mob->pt_root_page = vmw_piter_dma_addr(&iter);
} else if (vsgt->num_regions == 1) {
mob->pt_level = SVGA3D_MOBFMT_RANGE;
@@ -124,6 +136,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
goto out_no_populate;
vmw_mob_pt_setup(mob, iter, otable->size >> PAGE_SHIFT);
+ mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1;
}
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
@@ -133,7 +146,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
}
memset(cmd, 0, sizeof(*cmd));
- cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE;
+ cmd->header.id = VMW_ID_SET_OTABLE_BASE;
cmd->header.size = sizeof(cmd->body);
cmd->body.type = type;
cmd->body.baseAddress = mob->pt_root_page >> PAGE_SHIFT;
@@ -141,6 +154,13 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
cmd->body.validSizeInBytes = 0;
cmd->body.ptDepth = mob->pt_level;
+ /*
+ * The device doesn't support this, But the otable size is
+ * determined at compile-time, so this BUG shouldn't trigger
+ * randomly.
+ */
+ BUG_ON(mob->pt_level == VMW_MOBFMT_PTDEPTH_2);
+
vmw_fifo_commit(dev_priv, sizeof(*cmd));
otable->page_table = mob;
@@ -403,6 +423,27 @@ out_unreserve:
return ret;
}
+/**
+ * vmw_mob_assign_ppn - Assign a value to a page table entry
+ *
+ * @addr: Pointer to pointer to page table entry.
+ * @val: The page table entry
+ *
+ * Assigns a value to a page table entry pointed to by *@addr and increments
+ * *@addr according to the page table entry size.
+ */
+#if (VMW_PPN_SIZE == 8)
+static void vmw_mob_assign_ppn(uint32_t **addr, dma_addr_t val)
+{
+ *((uint64_t *) *addr) = val >> PAGE_SHIFT;
+ *addr += 2;
+}
+#else
+static void vmw_mob_assign_ppn(uint32_t **addr, dma_addr_t val)
+{
+ *(*addr)++ = val >> PAGE_SHIFT;
+}
+#endif
/*
* vmw_mob_build_pt - Build a pagetable
@@ -432,8 +473,8 @@ static unsigned long vmw_mob_build_pt(struct vmw_piter *data_iter,
save_addr = addr = kmap_atomic(page);
for (i = 0; i < PAGE_SIZE / VMW_PPN_SIZE; ++i) {
- u32 tmp = vmw_piter_dma_addr(data_iter) >> PAGE_SHIFT;
- *addr++ = tmp;
+ vmw_mob_assign_ppn(&addr,
+ vmw_piter_dma_addr(data_iter));
if (unlikely(--num_data_pages == 0))
break;
WARN_ON(!vmw_piter_next(data_iter));
@@ -565,7 +606,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
struct vmw_piter data_iter;
struct {
SVGA3dCmdHeader header;
- SVGA3dCmdDefineGBMob body;
+ vmw_cmd_define_gb_mob body;
} *cmd;
mob->id = mob_id;
@@ -574,7 +615,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
return 0;
if (likely(num_data_pages == 1)) {
- mob->pt_level = SVGA3D_MOBFMT_PTDEPTH_0;
+ mob->pt_level = VMW_MOBFMT_PTDEPTH_0;
mob->pt_root_page = vmw_piter_dma_addr(&data_iter);
} else if (vsgt->num_regions == 1) {
mob->pt_level = SVGA3D_MOBFMT_RANGE;
@@ -586,6 +627,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
vmw_mob_pt_setup(mob, data_iter, num_data_pages);
pt_set_up = true;
+ mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1;
}
(void) vmw_3d_resource_inc(dev_priv, false);
@@ -597,7 +639,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
goto out_no_cmd_space;
}
- cmd->header.id = SVGA_3D_CMD_DEFINE_GB_MOB;
+ cmd->header.id = VMW_ID_DEFINE_GB_MOB;
cmd->header.size = sizeof(cmd->body);
cmd->body.mobid = mob_id;
cmd->body.ptDepth = mob->pt_level;