2019-10-25 16:37:22 +01:00
// SPDX-License-Identifier: MIT
/*
* Copyright © 2019 Intel Corporation
*/
# include "i915_drv.h"
# include "intel_memory_region.h"
# include "gem/i915_gem_lmem.h"
# include "gem/i915_gem_region.h"
# include "intel_region_lmem.h"
2019-10-30 17:33:20 +00:00
static int init_fake_lmem_bar ( struct intel_memory_region * mem )
{
struct drm_i915_private * i915 = mem - > i915 ;
struct i915_ggtt * ggtt = & i915 - > ggtt ;
unsigned long n ;
int ret ;
/* We want to 1:1 map the mappable aperture to our reserved region */
mem - > fake_mappable . start = 0 ;
mem - > fake_mappable . size = resource_size ( & mem - > region ) ;
mem - > fake_mappable . color = I915_COLOR_UNEVICTABLE ;
ret = drm_mm_reserve_node ( & ggtt - > vm . mm , & mem - > fake_mappable ) ;
if ( ret )
return ret ;
mem - > remap_addr = dma_map_resource ( & i915 - > drm . pdev - > dev ,
mem - > region . start ,
mem - > fake_mappable . size ,
PCI_DMA_BIDIRECTIONAL ,
DMA_ATTR_FORCE_CONTIGUOUS ) ;
if ( dma_mapping_error ( & i915 - > drm . pdev - > dev , mem - > remap_addr ) ) {
drm_mm_remove_node ( & mem - > fake_mappable ) ;
return - EINVAL ;
}
for ( n = 0 ; n < mem - > fake_mappable . size > > PAGE_SHIFT ; + + n ) {
ggtt - > vm . insert_page ( & ggtt - > vm ,
mem - > remap_addr + ( n < < PAGE_SHIFT ) ,
n < < PAGE_SHIFT ,
I915_CACHE_NONE , 0 ) ;
}
mem - > region = ( struct resource ) DEFINE_RES_MEM ( mem - > remap_addr ,
mem - > fake_mappable . size ) ;
return 0 ;
}
static void release_fake_lmem_bar ( struct intel_memory_region * mem )
{
2019-11-06 12:31:35 +00:00
if ( ! drm_mm_node_allocated ( & mem - > fake_mappable ) )
return ;
drm_mm_remove_node ( & mem - > fake_mappable ) ;
2019-10-30 17:33:20 +00:00
dma_unmap_resource ( & mem - > i915 - > drm . pdev - > dev ,
mem - > remap_addr ,
mem - > fake_mappable . size ,
PCI_DMA_BIDIRECTIONAL ,
DMA_ATTR_FORCE_CONTIGUOUS ) ;
}
2019-10-25 16:37:23 +01:00
static void
region_lmem_release ( struct intel_memory_region * mem )
{
2019-10-30 17:33:20 +00:00
release_fake_lmem_bar ( mem ) ;
2019-10-25 16:37:23 +01:00
io_mapping_fini ( & mem - > iomap ) ;
intel_memory_region_release_buddy ( mem ) ;
}
static int
region_lmem_init ( struct intel_memory_region * mem )
{
int ret ;
2020-06-18 18:04:02 +03:00
if ( mem - > i915 - > params . fake_lmem_start ) {
2019-10-30 17:33:20 +00:00
ret = init_fake_lmem_bar ( mem ) ;
GEM_BUG_ON ( ret ) ;
}
2019-10-25 16:37:23 +01:00
if ( ! io_mapping_init_wc ( & mem - > iomap ,
mem - > io_start ,
resource_size ( & mem - > region ) ) )
return - EIO ;
ret = intel_memory_region_init_buddy ( mem ) ;
if ( ret )
io_mapping_fini ( & mem - > iomap ) ;
2019-12-27 19:07:48 +05:30
intel_memory_region_set_name ( mem , " local " ) ;
2019-10-25 16:37:23 +01:00
return ret ;
}
2019-10-25 16:37:22 +01:00
const struct intel_memory_region_ops intel_region_lmem_ops = {
2019-10-25 16:37:23 +01:00
. init = region_lmem_init ,
. release = region_lmem_release ,
2019-10-25 16:37:22 +01:00
. create_object = __i915_gem_lmem_object_create ,
} ;
2019-10-30 17:33:20 +00:00
struct intel_memory_region *
intel_setup_fake_lmem ( struct drm_i915_private * i915 )
{
struct pci_dev * pdev = i915 - > drm . pdev ;
struct intel_memory_region * mem ;
resource_size_t mappable_end ;
resource_size_t io_start ;
resource_size_t start ;
GEM_BUG_ON ( i915_ggtt_has_aperture ( & i915 - > ggtt ) ) ;
2020-06-18 18:04:02 +03:00
GEM_BUG_ON ( ! i915 - > params . fake_lmem_start ) ;
2019-10-30 17:33:20 +00:00
/* Your mappable aperture belongs to me now! */
mappable_end = pci_resource_len ( pdev , 2 ) ;
io_start = pci_resource_start ( pdev , 2 ) ,
2020-06-18 18:04:02 +03:00
start = i915 - > params . fake_lmem_start ;
2019-10-30 17:33:20 +00:00
mem = intel_memory_region_create ( i915 ,
start ,
mappable_end ,
PAGE_SIZE ,
io_start ,
& intel_region_lmem_ops ) ;
if ( ! IS_ERR ( mem ) ) {
2020-01-07 18:13:31 +03:00
drm_info ( & i915 - > drm , " Intel graphics fake LMEM: %pR \n " ,
& mem - > region ) ;
drm_info ( & i915 - > drm ,
" Intel graphics fake LMEM IO start: %llx \n " ,
( u64 ) mem - > io_start ) ;
drm_info ( & i915 - > drm , " Intel graphics fake LMEM size: %llx \n " ,
2019-10-30 17:33:20 +00:00
( u64 ) resource_size ( & mem - > region ) ) ;
}
return mem ;
}