aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2014-01-15 04:04:07 -0500
committerThomas Hellstrom <thellstrom@vmware.com>2014-01-17 01:52:40 -0500
commitf2a0dcb1aa23eea8f186b4773a653e61d509b17a (patch)
tree78da88ecb806b272086a84e8d26b4f4e503a19a6 /drivers/gpu
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')
-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 @@
35#include "svga_reg.h" 35#include "svga_reg.h"
36 36
37typedef uint32 PPN; 37typedef uint32 PPN;
38typedef __le64 PPN64;
38 39
39/* 40/*
40 * 3D Hardware Version 41 * 3D Hardware Version
@@ -1200,7 +1201,7 @@ typedef enum {
1200#define SVGA_3D_CMD_DESTROY_GB_SHADER 1113 1201#define SVGA_3D_CMD_DESTROY_GB_SHADER 1113
1201#define SVGA_3D_CMD_BIND_GB_SHADER 1114 1202#define SVGA_3D_CMD_BIND_GB_SHADER 1114
1202 1203
1203#define SVGA_3D_CMD_BIND_SHADERCONSTS 1115 1204#define SVGA_3D_CMD_SET_OTABLE_BASE64 1115
1204 1205
1205#define SVGA_3D_CMD_BEGIN_GB_QUERY 1116 1206#define SVGA_3D_CMD_BEGIN_GB_QUERY 1116
1206#define SVGA_3D_CMD_END_GB_QUERY 1117 1207#define SVGA_3D_CMD_END_GB_QUERY 1117
@@ -1223,7 +1224,10 @@ typedef enum {
1223 1224
1224#define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130 1225#define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130
1225 1226
1226#define SVGA_3D_CMD_MAX 1131 1227#define SVGA_3D_CMD_DEFINE_GB_MOB64 1135
1228#define SVGA_3D_CMD_REDEFINE_GB_MOB64 1136
1229
1230#define SVGA_3D_CMD_MAX 1142
1227#define SVGA_3D_CMD_FUTURE_MAX 3000 1231#define SVGA_3D_CMD_FUTURE_MAX 3000
1228 1232
1229/* 1233/*
@@ -1927,6 +1931,9 @@ typedef enum SVGAMobFormat {
1927 SVGA3D_MOBFMT_PTDEPTH_1 = 1, 1931 SVGA3D_MOBFMT_PTDEPTH_1 = 1,
1928 SVGA3D_MOBFMT_PTDEPTH_2 = 2, 1932 SVGA3D_MOBFMT_PTDEPTH_2 = 2,
1929 SVGA3D_MOBFMT_RANGE = 3, 1933 SVGA3D_MOBFMT_RANGE = 3,
1934 SVGA3D_MOBFMT_PTDEPTH64_0 = 4,
1935 SVGA3D_MOBFMT_PTDEPTH64_1 = 5,
1936 SVGA3D_MOBFMT_PTDEPTH64_2 = 6,
1930 SVGA3D_MOBFMT_MAX, 1937 SVGA3D_MOBFMT_MAX,
1931} SVGAMobFormat; 1938} SVGAMobFormat;
1932 1939
@@ -1971,6 +1978,15 @@ struct {
1971typedef 1978typedef
1972struct { 1979struct {
1973 SVGAOTableType type; 1980 SVGAOTableType type;
1981 PPN64 baseAddress;
1982 uint32 sizeInBytes;
1983 uint32 validSizeInBytes;
1984 SVGAMobFormat ptDepth;
1985} SVGA3dCmdSetOTableBase64; /* SVGA_3D_CMD_SET_OTABLE_BASE64 */
1986
1987typedef
1988struct {
1989 SVGAOTableType type;
1974} SVGA3dCmdReadbackOTable; /* SVGA_3D_CMD_READBACK_OTABLE */ 1990} SVGA3dCmdReadbackOTable; /* SVGA_3D_CMD_READBACK_OTABLE */
1975 1991
1976/* 1992/*
@@ -2008,6 +2024,32 @@ struct SVGA3dCmdRedefineGBMob {
2008} SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */ 2024} SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */
2009 2025
2010/* 2026/*
2027 * Define a memory object (Mob) in the OTable with a PPN64 base.
2028 */
2029
2030typedef
2031struct SVGA3dCmdDefineGBMob64 {
2032 SVGAMobId mobid;
2033 SVGAMobFormat ptDepth;
2034 PPN64 base;
2035 uint32 sizeInBytes;
2036}
2037SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */
2038
2039/*
2040 * Redefine an object in the OTable with PPN64 base.
2041 */
2042
2043typedef
2044struct SVGA3dCmdRedefineGBMob64 {
2045 SVGAMobId mobid;
2046 SVGAMobFormat ptDepth;
2047 PPN64 base;
2048 uint32 sizeInBytes;
2049}
2050SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */
2051
2052/*
2011 * Notification that the page tables have been modified. 2053 * Notification that the page tables have been modified.
2012 */ 2054 */
2013 2055
@@ -2243,14 +2285,6 @@ typedef struct SVGA3dCmdDestroyGBShader {
2243 uint32 shid; 2285 uint32 shid;
2244} SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */ 2286} SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */
2245 2287
2246
2247typedef struct SVGA3dCmdBindGBShaderConsts {
2248 uint32 cid;
2249 SVGA3dShaderType shaderType;
2250 SVGA3dShaderConstType shaderConstType;
2251 uint32 sid;
2252} SVGA3dCmdBindGBShaderConsts; /* SVGA_3D_CMD_BIND_SHADERCONSTS */
2253
2254typedef 2288typedef
2255struct { 2289struct {
2256 uint32 cid; 2290 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] = {
1730 true, false, true), 1730 true, false, true),
1731 VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SHADER, &vmw_cmd_invalid, 1731 VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SHADER, &vmw_cmd_invalid,
1732 false, false, true), 1732 false, false, true),
1733 VMW_CMD_DEF(SVGA_3D_CMD_BIND_SHADERCONSTS, &vmw_cmd_invalid, 1733 VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE64, &vmw_cmd_invalid,
1734 false, false, false), 1734 false, false, false),
1735 VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_GB_QUERY, &vmw_cmd_begin_gb_query, 1735 VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_GB_QUERY, &vmw_cmd_begin_gb_query,
1736 true, false, true), 1736 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 @@
33 33
34#define VMW_OTABLE_SETUP_SUB ((VMWGFX_ENABLE_SCREEN_TARGET_OTABLE) ? 0 : 1) 34#define VMW_OTABLE_SETUP_SUB ((VMWGFX_ENABLE_SCREEN_TARGET_OTABLE) ? 0 : 1)
35 35
36/* 36#ifdef CONFIG_64BIT
37 * Currently the MOB interface does not support 64-bit page frame numbers. 37#define VMW_PPN_SIZE 8
38 * This might change in the future to be similar to the GMR2 interface 38#define vmw_cmd_set_otable_base SVGA3dCmdSetOTableBase64
39 * when virtual machines support memory beyond 16TB. 39#define VMW_ID_SET_OTABLE_BASE SVGA_3D_CMD_SET_OTABLE_BASE64
40 */ 40#define vmw_cmd_define_gb_mob SVGA3dCmdDefineGBMob64
41 41#define VMW_ID_DEFINE_GB_MOB SVGA_3D_CMD_DEFINE_GB_MOB64
42#define VMW_MOBFMT_PTDEPTH_0 SVGA3D_MOBFMT_PTDEPTH64_0
43#define VMW_MOBFMT_PTDEPTH_1 SVGA3D_MOBFMT_PTDEPTH64_1
44#define VMW_MOBFMT_PTDEPTH_2 SVGA3D_MOBFMT_PTDEPTH64_2
45#else
42#define VMW_PPN_SIZE 4 46#define VMW_PPN_SIZE 4
47#define vmw_cmd_set_otable_base SVGA3dCmdSetOTableBase
48#define VMW_ID_SET_OTABLE_BASE SVGA_3D_CMD_SET_OTABLE_BASE
49#define vmw_cmd_define_gb_mob SVGA3dCmdDefineGBMob
50#define VMW_ID_DEFINE_GB_MOB SVGA_3D_CMD_DEFINE_GB_MOB
51#define VMW_MOBFMT_PTDEPTH_0 SVGA3D_MOBFMT_PTDEPTH_0
52#define VMW_MOBFMT_PTDEPTH_1 SVGA3D_MOBFMT_PTDEPTH_1
53#define VMW_MOBFMT_PTDEPTH_2 SVGA3D_MOBFMT_PTDEPTH_2
54#endif
43 55
44/* 56/*
45 * struct vmw_mob - Structure containing page table and metadata for a 57 * 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,
93{ 105{
94 struct { 106 struct {
95 SVGA3dCmdHeader header; 107 SVGA3dCmdHeader header;
96 SVGA3dCmdSetOTableBase body; 108 vmw_cmd_set_otable_base body;
97 } *cmd; 109 } *cmd;
98 struct vmw_mob *mob; 110 struct vmw_mob *mob;
99 const struct vmw_sg_table *vsgt; 111 const struct vmw_sg_table *vsgt;
@@ -113,7 +125,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
113 } 125 }
114 126
115 if (otable->size <= PAGE_SIZE) { 127 if (otable->size <= PAGE_SIZE) {
116 mob->pt_level = SVGA3D_MOBFMT_PTDEPTH_0; 128 mob->pt_level = VMW_MOBFMT_PTDEPTH_0;
117 mob->pt_root_page = vmw_piter_dma_addr(&iter); 129 mob->pt_root_page = vmw_piter_dma_addr(&iter);
118 } else if (vsgt->num_regions == 1) { 130 } else if (vsgt->num_regions == 1) {
119 mob->pt_level = SVGA3D_MOBFMT_RANGE; 131 mob->pt_level = SVGA3D_MOBFMT_RANGE;
@@ -124,6 +136,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
124 goto out_no_populate; 136 goto out_no_populate;
125 137
126 vmw_mob_pt_setup(mob, iter, otable->size >> PAGE_SHIFT); 138 vmw_mob_pt_setup(mob, iter, otable->size >> PAGE_SHIFT);
139 mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1;
127 } 140 }
128 141
129 cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); 142 cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
@@ -133,7 +146,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
133 } 146 }
134 147
135 memset(cmd, 0, sizeof(*cmd)); 148 memset(cmd, 0, sizeof(*cmd));
136 cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE; 149 cmd->header.id = VMW_ID_SET_OTABLE_BASE;
137 cmd->header.size = sizeof(cmd->body); 150 cmd->header.size = sizeof(cmd->body);
138 cmd->body.type = type; 151 cmd->body.type = type;
139 cmd->body.baseAddress = mob->pt_root_page >> PAGE_SHIFT; 152 cmd->body.baseAddress = mob->pt_root_page >> PAGE_SHIFT;
@@ -141,6 +154,13 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
141 cmd->body.validSizeInBytes = 0; 154 cmd->body.validSizeInBytes = 0;
142 cmd->body.ptDepth = mob->pt_level; 155 cmd->body.ptDepth = mob->pt_level;
143 156
157 /*
158 * The device doesn't support this, But the otable size is
159 * determined at compile-time, so this BUG shouldn't trigger
160 * randomly.
161 */
162 BUG_ON(mob->pt_level == VMW_MOBFMT_PTDEPTH_2);
163
144 vmw_fifo_commit(dev_priv, sizeof(*cmd)); 164 vmw_fifo_commit(dev_priv, sizeof(*cmd));
145 otable->page_table = mob; 165 otable->page_table = mob;
146 166
@@ -403,6 +423,27 @@ out_unreserve:
403 return ret; 423 return ret;
404} 424}
405 425
426/**
427 * vmw_mob_assign_ppn - Assign a value to a page table entry
428 *
429 * @addr: Pointer to pointer to page table entry.
430 * @val: The page table entry
431 *
432 * Assigns a value to a page table entry pointed to by *@addr and increments
433 * *@addr according to the page table entry size.
434 */
435#if (VMW_PPN_SIZE == 8)
436static void vmw_mob_assign_ppn(uint32_t **addr, dma_addr_t val)
437{
438 *((uint64_t *) *addr) = val >> PAGE_SHIFT;
439 *addr += 2;
440}
441#else
442static void vmw_mob_assign_ppn(uint32_t **addr, dma_addr_t val)
443{
444 *(*addr)++ = val >> PAGE_SHIFT;
445}
446#endif
406 447
407/* 448/*
408 * vmw_mob_build_pt - Build a pagetable 449 * vmw_mob_build_pt - Build a pagetable
@@ -432,8 +473,8 @@ static unsigned long vmw_mob_build_pt(struct vmw_piter *data_iter,
432 save_addr = addr = kmap_atomic(page); 473 save_addr = addr = kmap_atomic(page);
433 474
434 for (i = 0; i < PAGE_SIZE / VMW_PPN_SIZE; ++i) { 475 for (i = 0; i < PAGE_SIZE / VMW_PPN_SIZE; ++i) {
435 u32 tmp = vmw_piter_dma_addr(data_iter) >> PAGE_SHIFT; 476 vmw_mob_assign_ppn(&addr,
436 *addr++ = tmp; 477 vmw_piter_dma_addr(data_iter));
437 if (unlikely(--num_data_pages == 0)) 478 if (unlikely(--num_data_pages == 0))
438 break; 479 break;
439 WARN_ON(!vmw_piter_next(data_iter)); 480 WARN_ON(!vmw_piter_next(data_iter));
@@ -565,7 +606,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
565 struct vmw_piter data_iter; 606 struct vmw_piter data_iter;
566 struct { 607 struct {
567 SVGA3dCmdHeader header; 608 SVGA3dCmdHeader header;
568 SVGA3dCmdDefineGBMob body; 609 vmw_cmd_define_gb_mob body;
569 } *cmd; 610 } *cmd;
570 611
571 mob->id = mob_id; 612 mob->id = mob_id;
@@ -574,7 +615,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
574 return 0; 615 return 0;
575 616
576 if (likely(num_data_pages == 1)) { 617 if (likely(num_data_pages == 1)) {
577 mob->pt_level = SVGA3D_MOBFMT_PTDEPTH_0; 618 mob->pt_level = VMW_MOBFMT_PTDEPTH_0;
578 mob->pt_root_page = vmw_piter_dma_addr(&data_iter); 619 mob->pt_root_page = vmw_piter_dma_addr(&data_iter);
579 } else if (vsgt->num_regions == 1) { 620 } else if (vsgt->num_regions == 1) {
580 mob->pt_level = SVGA3D_MOBFMT_RANGE; 621 mob->pt_level = SVGA3D_MOBFMT_RANGE;
@@ -586,6 +627,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
586 627
587 vmw_mob_pt_setup(mob, data_iter, num_data_pages); 628 vmw_mob_pt_setup(mob, data_iter, num_data_pages);
588 pt_set_up = true; 629 pt_set_up = true;
630 mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1;
589 } 631 }
590 632
591 (void) vmw_3d_resource_inc(dev_priv, false); 633 (void) vmw_3d_resource_inc(dev_priv, false);
@@ -597,7 +639,7 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
597 goto out_no_cmd_space; 639 goto out_no_cmd_space;
598 } 640 }
599 641
600 cmd->header.id = SVGA_3D_CMD_DEFINE_GB_MOB; 642 cmd->header.id = VMW_ID_DEFINE_GB_MOB;
601 cmd->header.size = sizeof(cmd->body); 643 cmd->header.size = sizeof(cmd->body);
602 cmd->body.mobid = mob_id; 644 cmd->body.mobid = mob_id;
603 cmd->body.ptDepth = mob->pt_level; 645 cmd->body.ptDepth = mob->pt_level;