@@ -214,20 +214,6 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
pci_unmap_page((dev)->pdev, (pt)->daddr, 4096, PCI_DMA_BIDIRECTIONAL); \
} while (0);
-
-static void dma_unmap_pt_range(struct i915_pagedir *pd,
- unsigned pde, size_t n,
- struct drm_device *dev)
-{
- if (WARN_ON(pde + n > I915_PDES_PER_PD))
- n = I915_PDES_PER_PD - pde;
-
- n += pde;
-
- for (; pde < n; pde++)
- dma_unmap_pt_single(pd->page_tables[pde], dev);
-}
-
/**
* dma_map_pt_single() - Create a dma mapping for a page table
* @pt: Page table to get a DMA map for
@@ -257,33 +243,12 @@ static int dma_map_pt_single(struct i915_pagetab *pt, struct drm_device *dev)
return 0;
}
-static int dma_map_pt_range(struct i915_pagedir *pd,
- unsigned pde, size_t n,
- struct drm_device *dev)
-{
- const int first = pde;
-
- if (WARN_ON(pde + n > I915_PDES_PER_PD))
- n = I915_PDES_PER_PD - pde;
-
- n += pde;
-
- for (; pde < n; pde++) {
- int ret;
- ret = dma_map_pt_single(pd->page_tables[pde], dev);
- if (ret) {
- dma_unmap_pt_range(pd, first, pde, dev);
- return ret;
- }
- }
-
- return 0;
-}
-
-static void free_pt_single(struct i915_pagetab *pt)
+static void free_pt_single(struct i915_pagetab *pt, struct drm_device *dev)
{
if (WARN_ON(!pt->page))
return;
+
+ dma_unmap_pt_single(pt, dev);
__free_page(pt->page);
kfree(pt);
}
@@ -291,6 +256,7 @@ static void free_pt_single(struct i915_pagetab *pt)
static struct i915_pagetab *alloc_pt_single(struct drm_device *dev)
{
struct i915_pagetab *pt;
+ int ret;
pt = kzalloc(sizeof(*pt), GFP_KERNEL);
if (!pt)
@@ -302,6 +268,13 @@ static struct i915_pagetab *alloc_pt_single(struct drm_device *dev)
return ERR_PTR(-ENOMEM);
}
+ ret = dma_map_pt_single(pt, dev);
+ if (ret) {
+ __free_page(pt->page);
+ kfree(pt);
+ return ERR_PTR(ret);
+ }
+
return pt;
}
@@ -345,7 +318,7 @@ static int alloc_pt_range(struct i915_pagedir *pd, uint16_t pde, size_t count,
err_out:
while (i--)
- free_pt_single(pd->page_tables[i]);
+ free_pt_single(pd->page_tables[i], dev);
return ret;
}
@@ -512,7 +485,7 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
}
}
-static void gen8_free_page_tables(struct i915_pagedir *pd)
+static void gen8_free_page_tables(struct i915_pagedir *pd, struct drm_device *dev)
{
int i;
@@ -520,7 +493,7 @@ static void gen8_free_page_tables(struct i915_pagedir *pd)
return;
for (i = 0; i < I915_PDES_PER_PD; i++) {
- free_pt_single(pd->page_tables[i]);
+ free_pt_single(pd->page_tables[i], dev);
pd->page_tables[i] = NULL;
}
}
@@ -530,7 +503,7 @@ static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
int i;
for (i = 0; i < ppgtt->num_pd_pages; i++) {
- gen8_free_page_tables(ppgtt->pdp.pagedir[i]);
+ gen8_free_page_tables(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
free_pd_single(ppgtt->pdp.pagedir[i]);
}
}
@@ -584,7 +557,7 @@ static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt)
unwind_out:
while (i--)
- gen8_free_page_tables(ppgtt->pdp.pagedir[i]);
+ gen8_free_page_tables(ppgtt->pdp.pagedir[i], ppgtt->base.dev);
return -ENOMEM;
}
@@ -682,18 +655,9 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
* 2. Create DMA mappings for the page directories and page tables.
*/
for (i = 0; i < max_pdp; i++) {
- struct i915_pagedir *pd;
ret = gen8_ppgtt_setup_page_directories(ppgtt, i);
if (ret)
goto bail;
-
- pd = ppgtt->pdp.pagedir[i];
-
- for (j = 0; j < I915_PDES_PER_PD; j++) {
- ret = dma_map_pt_single(pd->page_tables[j], ppgtt->base.dev);
- if (ret)
- goto bail;
- }
}
/*
@@ -1029,7 +993,7 @@ static void gen6_ppgtt_free(struct i915_hw_ppgtt *ppgtt)
int i;
for (i = 0; i < ppgtt->num_pd_entries; i++)
- free_pt_single(ppgtt->pd.page_tables[i]);
+ free_pt_single(ppgtt->pd.page_tables[i], ppgtt->base.dev);
free_pd_single(&ppgtt->pd);
}
@@ -1041,7 +1005,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
drm_mm_remove_node(&ppgtt->node);
- dma_unmap_pt_range(&ppgtt->pd, 0, ppgtt->num_pd_entries, vm->dev);
gen6_ppgtt_free(ppgtt);
}
@@ -1125,13 +1088,6 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
if (ret)
return ret;
- ret = dma_map_pt_range(&ppgtt->pd, 0, ppgtt->num_pd_entries,
- ppgtt->base.dev);
- if (ret) {
- gen6_ppgtt_free(ppgtt);
- return ret;
- }
-
ppgtt->base.clear_range = gen6_ppgtt_clear_range;
ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
ppgtt->base.cleanup = gen6_ppgtt_cleanup;