From f2a0dcb1aa23eea8f186b4773a653e61d509b17a Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 15 Jan 2014 10:04:07 +0100 Subject: [PATCH] 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 Reviewed-by: Jakob Bornecrantz --- drivers/gpu/drm/vmwgfx/svga3d_reg.h | 54 ++++++++++++++++++++----- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 +- 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 fce351b..b1e5d2c 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 b924fd6..7a5f1eb 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 388b64d..ad29651 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; -- 2.7.4