#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_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_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
{
struct {
SVGA3dCmdHeader header;
- SVGA3dCmdSetOTableBase body;
+ SVGA3dCmdSetOTableBase64 body;
} *cmd;
struct vmw_mob *mob;
const struct vmw_sg_table *vsgt;
}
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;
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));
}
memset(cmd, 0, sizeof(*cmd));
- cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE;
+ cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE64;
cmd->header.size = sizeof(cmd->body);
cmd->body.type = type;
- cmd->body.baseAddress = mob->pt_root_page >> PAGE_SHIFT;
+ cmd->body.baseAddress = cpu_to_le64(mob->pt_root_page >> PAGE_SHIFT);
cmd->body.sizeInBytes = otable->size;
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;
SVGA3dCmdHeader header;
SVGA3dCmdSetOTableBase body;
} *cmd;
- struct ttm_buffer_object *bo = otable->page_table->pt_bo;
+ struct ttm_buffer_object *bo;
if (otable->page_table == NULL)
return;
+ bo = otable->page_table->pt_bo;
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
if (unlikely(cmd == NULL))
DRM_ERROR("Failed reserving FIFO space for OTable setup.\n");
if (bo) {
int ret;
- ret = ttm_bo_reserve(bo, false, true, false, false);
+ ret = ttm_bo_reserve(bo, false, true, false, NULL);
BUG_ON(ret != 0);
vmw_fence_single_bo(bo, NULL);
if (unlikely(ret != 0))
goto out_no_bo;
- ret = ttm_bo_reserve(dev_priv->otable_bo, false, true, false, false);
+ ret = ttm_bo_reserve(dev_priv->otable_bo, false, true, false, NULL);
BUG_ON(ret != 0);
ret = vmw_bo_driver.ttm_tt_populate(dev_priv->otable_bo->ttm);
if (unlikely(ret != 0))
vmw_takedown_otable_base(dev_priv, i,
&dev_priv->otables[i]);
- ret = ttm_bo_reserve(bo, false, true, false, false);
+ ret = ttm_bo_reserve(bo, false, true, false, NULL);
BUG_ON(ret != 0);
vmw_fence_single_bo(bo, NULL);
if (unlikely(ret != 0))
return ret;
- ret = ttm_bo_reserve(mob->pt_bo, false, true, false, false);
+ ret = ttm_bo_reserve(mob->pt_bo, false, true, false, NULL);
BUG_ON(ret != 0);
ret = vmw_bo_driver.ttm_tt_populate(mob->pt_bo->ttm);
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(__le32 **addr, dma_addr_t val)
+{
+ *((__le64 *) *addr) = cpu_to_le64(val >> PAGE_SHIFT);
+ *addr += 2;
+}
+#else
+static void vmw_mob_assign_ppn(__le32 **addr, dma_addr_t val)
+{
+ *(*addr)++ = cpu_to_le32(val >> PAGE_SHIFT);
+}
+#endif
/*
* vmw_mob_build_pt - Build a pagetable
unsigned long pt_size = num_data_pages * VMW_PPN_SIZE;
unsigned long num_pt_pages = DIV_ROUND_UP(pt_size, PAGE_SIZE);
unsigned long pt_page;
- uint32_t *addr, *save_addr;
+ __le32 *addr, *save_addr;
unsigned long i;
struct page *page;
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));
const struct vmw_sg_table *vsgt;
int ret;
- ret = ttm_bo_reserve(bo, false, true, false, 0);
+ ret = ttm_bo_reserve(bo, false, true, false, NULL);
BUG_ON(ret != 0);
vsgt = vmw_bo_sg_table(bo);
struct ttm_buffer_object *bo = mob->pt_bo;
if (bo) {
- ret = ttm_bo_reserve(bo, false, true, false, 0);
+ ret = ttm_bo_reserve(bo, false, true, false, NULL);
/*
* Noone else should be using this buffer.
*/
struct vmw_piter data_iter;
struct {
SVGA3dCmdHeader header;
- SVGA3dCmdDefineGBMob body;
+ SVGA3dCmdDefineGBMob64 body;
} *cmd;
mob->id = mob_id;
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;
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);
goto out_no_cmd_space;
}
- cmd->header.id = SVGA_3D_CMD_DEFINE_GB_MOB;
+ cmd->header.id = SVGA_3D_CMD_DEFINE_GB_MOB64;
cmd->header.size = sizeof(cmd->body);
cmd->body.mobid = mob_id;
cmd->body.ptDepth = mob->pt_level;
- cmd->body.base = mob->pt_root_page >> PAGE_SHIFT;
+ cmd->body.base = cpu_to_le64(mob->pt_root_page >> PAGE_SHIFT);
cmd->body.sizeInBytes = num_data_pages * PAGE_SIZE;
vmw_fifo_commit(dev_priv, sizeof(*cmd));