drm/i915/gtt: allow overriding the pt alignment

On some platforms we have alignment restrictions when accessing LMEM
from the GTT. In the next few patches we need to be able to modify the
page-tables directly via the GTT itself.

Suggested-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220218184752.7524-10-ramalingam.c@intel.com
This commit is contained in:
Matthew Auld
2022-02-19 00:17:46 +05:30
committed by Lucas De Marchi
parent a413c99fc1
commit 2cff4b9ed6
2 changed files with 21 additions and 5 deletions

View File

@@ -200,6 +200,14 @@ void *__px_vaddr(struct drm_i915_gem_object *p);
struct i915_vm_pt_stash {
/* preallocated chains of page tables/directories */
struct i915_page_table *pt[2];
/*
* Optionally override the alignment/size of the physical page that
* contains each PT. If not set defaults back to the usual
* I915_GTT_PAGE_SIZE_4K. This does not influence the other paging
* structures. MUST be a power-of-two. ONLY applicable on discrete
* platforms.
*/
int pt_sz;
};
struct i915_vma_ops {
@@ -595,7 +603,7 @@ void free_scratch(struct i915_address_space *vm);
struct drm_i915_gem_object *alloc_pt_dma(struct i915_address_space *vm, int sz);
struct drm_i915_gem_object *alloc_pt_lmem(struct i915_address_space *vm, int sz);
struct i915_page_table *alloc_pt(struct i915_address_space *vm);
struct i915_page_table *alloc_pt(struct i915_address_space *vm, int sz);
struct i915_page_directory *alloc_pd(struct i915_address_space *vm);
struct i915_page_directory *__alloc_pd(int npde);

View File

@@ -12,7 +12,7 @@
#include "gen6_ppgtt.h"
#include "gen8_ppgtt.h"
struct i915_page_table *alloc_pt(struct i915_address_space *vm)
struct i915_page_table *alloc_pt(struct i915_address_space *vm, int sz)
{
struct i915_page_table *pt;
@@ -20,7 +20,7 @@ struct i915_page_table *alloc_pt(struct i915_address_space *vm)
if (unlikely(!pt))
return ERR_PTR(-ENOMEM);
pt->base = vm->alloc_pt_dma(vm, I915_GTT_PAGE_SIZE_4K);
pt->base = vm->alloc_pt_dma(vm, sz);
if (IS_ERR(pt->base)) {
kfree(pt);
return ERR_PTR(-ENOMEM);
@@ -221,17 +221,25 @@ int i915_vm_alloc_pt_stash(struct i915_address_space *vm,
u64 size)
{
unsigned long count;
int shift, n;
int shift, n, pt_sz;
shift = vm->pd_shift;
if (!shift)
return 0;
pt_sz = stash->pt_sz;
if (!pt_sz)
pt_sz = I915_GTT_PAGE_SIZE_4K;
else
GEM_BUG_ON(!IS_DGFX(vm->i915));
GEM_BUG_ON(!is_power_of_2(pt_sz));
count = pd_count(size, shift);
while (count--) {
struct i915_page_table *pt;
pt = alloc_pt(vm);
pt = alloc_pt(vm, pt_sz);
if (IS_ERR(pt)) {
i915_vm_free_pt_stash(vm, stash);
return PTR_ERR(pt);