@ -387,50 +387,6 @@ fail_bitmap:
return ERR_PTR ( ret ) ;
}
/**
* alloc_pt_range ( ) - Allocate a multiple page tables
* @ pd : The page directory which will have at least @ count entries
* available to point to the allocated page tables .
* @ pde : First page directory entry for which we are allocating .
* @ count : Number of pages to allocate .
* @ dev : DRM device .
*
* Allocates multiple page table pages and sets the appropriate entries in the
* page table structure within the page directory . Function cleans up after
* itself on any failures .
*
* Return : 0 if allocation succeeded .
*/
static int alloc_pt_range ( struct i915_page_directory * pd , uint16_t pde , size_t count ,
struct drm_device * dev )
{
int i , ret ;
/* 512 is the max page tables per page_directory on any platform. */
if ( WARN_ON ( pde + count > I915_PDES ) )
return - EINVAL ;
for ( i = pde ; i < pde + count ; i + + ) {
struct i915_page_table * pt = alloc_pt_single ( dev ) ;
if ( IS_ERR ( pt ) ) {
ret = PTR_ERR ( pt ) ;
goto err_out ;
}
WARN ( pd - > page_table [ i ] ,
" Leaking page directory entry %d (%p) \n " ,
i , pd - > page_table [ i ] ) ;
pd - > page_table [ i ] = pt ;
}
return 0 ;
err_out :
while ( i - - > pde )
unmap_and_free_pt ( pd - > page_table [ i ] , dev ) ;
return ret ;
}
static void unmap_and_free_pd ( struct i915_page_directory * pd ,
struct drm_device * dev )
{
@ -971,7 +927,7 @@ err_out:
* space .
*
*/
static int gen8_ppgtt_init_common ( struct i915_hw_ppgtt * ppgtt , uint64_t size )
static int gen8_ppgtt_init ( struct i915_hw_ppgtt * ppgtt )
{
ppgtt - > scratch_pt = alloc_pt_single ( ppgtt - > base . dev ) ;
if ( IS_ERR ( ppgtt - > scratch_pt ) )
@ -985,8 +941,9 @@ static int gen8_ppgtt_init_common(struct i915_hw_ppgtt *ppgtt, uint64_t size)
gen8_initialize_pd ( & ppgtt - > base , ppgtt - > scratch_pd ) ;
ppgtt - > base . start = 0 ;
ppgtt - > base . total = size ;
ppgtt - > base . total = 1ULL < < 32 ;
ppgtt - > base . cleanup = gen8_ppgtt_cleanup ;
ppgtt - > base . allocate_va_range = gen8_alloc_va_range ;
ppgtt - > base . insert_entries = gen8_ppgtt_insert_entries ;
ppgtt - > base . clear_range = gen8_ppgtt_clear_range ;
ppgtt - > base . unbind_vma = ppgtt_unbind_vma ;
@ -997,46 +954,6 @@ static int gen8_ppgtt_init_common(struct i915_hw_ppgtt *ppgtt, uint64_t size)
return 0 ;
}
static int gen8_aliasing_ppgtt_init ( struct i915_hw_ppgtt * ppgtt )
{
struct drm_device * dev = ppgtt - > base . dev ;
struct drm_i915_private * dev_priv = dev - > dev_private ;
uint64_t start = 0 , size = dev_priv - > gtt . base . total ;
int ret ;
ret = gen8_ppgtt_init_common ( ppgtt , dev_priv - > gtt . base . total ) ;
if ( ret )
return ret ;
/* Aliasing PPGTT has to always work and be mapped because of the way we
* use RESTORE_INHIBIT in the context switch . This will be fixed
* eventually . */
ret = gen8_alloc_va_range ( & ppgtt - > base , start , size ) ;
if ( ret ) {
unmap_and_free_pd ( ppgtt - > scratch_pd , ppgtt - > base . dev ) ;
unmap_and_free_pt ( ppgtt - > scratch_pt , ppgtt - > base . dev ) ;
return ret ;
}
ppgtt - > base . allocate_va_range = NULL ;
ppgtt - > base . clear_range ( & ppgtt - > base , 0 , ppgtt - > base . total , true ) ;
return 0 ;
}
static int gen8_ppgtt_init ( struct i915_hw_ppgtt * ppgtt )
{
int ret ;
ret = gen8_ppgtt_init_common ( ppgtt , ( 1ULL < < 32 ) ) ;
if ( ret )
return ret ;
ppgtt - > base . allocate_va_range = gen8_alloc_va_range ;
return 0 ;
}
static void gen6_dump_ppgtt ( struct i915_hw_ppgtt * ppgtt , struct seq_file * m )
{
struct i915_address_space * vm = & ppgtt - > base ;
@ -1533,7 +1450,7 @@ static void gen6_scratch_va_range(struct i915_hw_ppgtt *ppgtt,
ppgtt - > pd . page_table [ pde ] = ppgtt - > scratch_pt ;
}
static int gen6_ppgtt_init ( struct i915_hw_ppgtt * ppgtt , bool aliasing )
static int gen6_ppgtt_init ( struct i915_hw_ppgtt * ppgtt )
{
struct drm_device * dev = ppgtt - > base . dev ;
struct drm_i915_private * dev_priv = dev - > dev_private ;
@ -1556,18 +1473,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt, bool aliasing)
if ( ret )
return ret ;
if ( aliasing ) {
/* preallocate all pts */
ret = alloc_pt_range ( & ppgtt - > pd , 0 , I915_PDES ,
ppgtt - > base . dev ) ;
if ( ret ) {
gen6_ppgtt_cleanup ( & ppgtt - > base ) ;
return ret ;
}
}
ppgtt - > base . allocate_va_range = aliasing ? NULL : gen6_alloc_va_range ;
ppgtt - > base . allocate_va_range = gen6_alloc_va_range ;
ppgtt - > base . clear_range = gen6_ppgtt_clear_range ;
ppgtt - > base . insert_entries = gen6_ppgtt_insert_entries ;
ppgtt - > base . unbind_vma = ppgtt_unbind_vma ;
@ -1583,9 +1489,6 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt, bool aliasing)
ppgtt - > pd_addr = ( gen6_pte_t __iomem * ) dev_priv - > gtt . gsm +
ppgtt - > pd . pd_offset / sizeof ( gen6_pte_t ) ;
if ( aliasing )
ppgtt - > base . clear_range ( & ppgtt - > base , 0 , ppgtt - > base . total , true ) ;
else
gen6_scratch_va_range ( ppgtt , 0 , ppgtt - > base . total ) ;
gen6_write_page_range ( dev_priv , & ppgtt - > pd , 0 , ppgtt - > base . total ) ;
@ -1600,8 +1503,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt, bool aliasing)
return 0 ;
}
static int __hw_ppgtt_init ( struct drm_device * dev , struct i915_hw_ppgtt * ppgtt ,
bool aliasing )
static int __hw_ppgtt_init ( struct drm_device * dev , struct i915_hw_ppgtt * ppgtt )
{
struct drm_i915_private * dev_priv = dev - > dev_private ;
@ -1609,9 +1511,7 @@ static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt,
ppgtt - > base . scratch = dev_priv - > gtt . base . scratch ;
if ( INTEL_INFO ( dev ) - > gen < 8 )
return gen6_ppgtt_init ( ppgtt , aliasing ) ;
else if ( aliasing )
return gen8_aliasing_ppgtt_init ( ppgtt ) ;
return gen6_ppgtt_init ( ppgtt ) ;
else
return gen8_ppgtt_init ( ppgtt ) ;
}
@ -1620,7 +1520,7 @@ int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
struct drm_i915_private * dev_priv = dev - > dev_private ;
int ret = 0 ;
ret = __hw_ppgtt_init ( dev , ppgtt , false ) ;
ret = __hw_ppgtt_init ( dev , ppgtt ) ;
if ( ret = = 0 ) {
kref_init ( & ppgtt - > ref ) ;
drm_mm_init ( & ppgtt - > base . mm , ppgtt - > base . start ,
@ -2255,13 +2155,27 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
if ( ! ppgtt )
return - ENOMEM ;
ret = __hw_ppgtt_init ( dev , ppgtt , true ) ;
ret = __hw_ppgtt_init ( dev , ppgtt ) ;
if ( ret ) {
ppgtt - > base . cleanup ( & ppgtt - > base ) ;
kfree ( ppgtt ) ;
return ret ;
}
if ( ppgtt - > base . allocate_va_range )
ret = ppgtt - > base . allocate_va_range ( & ppgtt - > base , 0 ,
ppgtt - > base . total ) ;
if ( ret ) {
ppgtt - > base . cleanup ( & ppgtt - > base ) ;
kfree ( ppgtt ) ;
return ret ;
}
ppgtt - > base . clear_range ( & ppgtt - > base ,
ppgtt - > base . start ,
ppgtt - > base . total ,
true ) ;
dev_priv - > mm . aliasing_ppgtt = ppgtt ;
}