diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2014-01-15 04:04:07 -0500 |
---|---|---|
committer | Thomas Hellstrom <thellstrom@vmware.com> | 2014-01-17 01:52:40 -0500 |
commit | f2a0dcb1aa23eea8f186b4773a653e61d509b17a (patch) | |
tree | 78da88ecb806b272086a84e8d26b4f4e503a19a6 /drivers | |
parent | b360a3cecd3a2e14e56798b570007d4763f21b74 (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')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/svga3d_reg.h | 54 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 70 |
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 | ||
37 | typedef uint32 PPN; | 37 | typedef uint32 PPN; |
38 | typedef __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 { | |||
1971 | typedef | 1978 | typedef |
1972 | struct { | 1979 | struct { |
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 | |||
1987 | typedef | ||
1988 | struct { | ||
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 | |||
2030 | typedef | ||
2031 | struct SVGA3dCmdDefineGBMob64 { | ||
2032 | SVGAMobId mobid; | ||
2033 | SVGAMobFormat ptDepth; | ||
2034 | PPN64 base; | ||
2035 | uint32 sizeInBytes; | ||
2036 | } | ||
2037 | SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */ | ||
2038 | |||
2039 | /* | ||
2040 | * Redefine an object in the OTable with PPN64 base. | ||
2041 | */ | ||
2042 | |||
2043 | typedef | ||
2044 | struct SVGA3dCmdRedefineGBMob64 { | ||
2045 | SVGAMobId mobid; | ||
2046 | SVGAMobFormat ptDepth; | ||
2047 | PPN64 base; | ||
2048 | uint32 sizeInBytes; | ||
2049 | } | ||
2050 | SVGA3dCmdRedefineGBMob64; /* 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 | |||
2247 | typedef struct SVGA3dCmdBindGBShaderConsts { | ||
2248 | uint32 cid; | ||
2249 | SVGA3dShaderType shaderType; | ||
2250 | SVGA3dShaderConstType shaderConstType; | ||
2251 | uint32 sid; | ||
2252 | } SVGA3dCmdBindGBShaderConsts; /* SVGA_3D_CMD_BIND_SHADERCONSTS */ | ||
2253 | |||
2254 | typedef | 2288 | typedef |
2255 | struct { | 2289 | struct { |
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) | ||
436 | static 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 | ||
442 | static 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; |