Home | History | Annotate | Line # | Download | only in i915
      1  1.1  riastrad /*	$NetBSD: intel_region_lmem.c,v 1.2 2021/12/18 23:45:28 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad // SPDX-License-Identifier: MIT
      4  1.1  riastrad /*
      5  1.1  riastrad  * Copyright  2019 Intel Corporation
      6  1.1  riastrad  */
      7  1.1  riastrad 
      8  1.1  riastrad #include <sys/cdefs.h>
      9  1.1  riastrad __KERNEL_RCSID(0, "$NetBSD: intel_region_lmem.c,v 1.2 2021/12/18 23:45:28 riastradh Exp $");
     10  1.1  riastrad 
     11  1.1  riastrad #include "i915_drv.h"
     12  1.1  riastrad #include "intel_memory_region.h"
     13  1.1  riastrad #include "gem/i915_gem_lmem.h"
     14  1.1  riastrad #include "gem/i915_gem_region.h"
     15  1.1  riastrad #include "intel_region_lmem.h"
     16  1.1  riastrad 
     17  1.1  riastrad static int init_fake_lmem_bar(struct intel_memory_region *mem)
     18  1.1  riastrad {
     19  1.1  riastrad 	struct drm_i915_private *i915 = mem->i915;
     20  1.1  riastrad 	struct i915_ggtt *ggtt = &i915->ggtt;
     21  1.1  riastrad 	unsigned long n;
     22  1.1  riastrad 	int ret;
     23  1.1  riastrad 
     24  1.1  riastrad 	/* We want to 1:1 map the mappable aperture to our reserved region */
     25  1.1  riastrad 
     26  1.1  riastrad 	mem->fake_mappable.start = 0;
     27  1.1  riastrad 	mem->fake_mappable.size = resource_size(&mem->region);
     28  1.1  riastrad 	mem->fake_mappable.color = I915_COLOR_UNEVICTABLE;
     29  1.1  riastrad 
     30  1.1  riastrad 	ret = drm_mm_reserve_node(&ggtt->vm.mm, &mem->fake_mappable);
     31  1.1  riastrad 	if (ret)
     32  1.1  riastrad 		return ret;
     33  1.1  riastrad 
     34  1.1  riastrad 	mem->remap_addr = dma_map_resource(&i915->drm.pdev->dev,
     35  1.1  riastrad 					   mem->region.start,
     36  1.1  riastrad 					   mem->fake_mappable.size,
     37  1.1  riastrad 					   PCI_DMA_BIDIRECTIONAL,
     38  1.1  riastrad 					   DMA_ATTR_FORCE_CONTIGUOUS);
     39  1.1  riastrad 	if (dma_mapping_error(&i915->drm.pdev->dev, mem->remap_addr)) {
     40  1.1  riastrad 		drm_mm_remove_node(&mem->fake_mappable);
     41  1.1  riastrad 		return -EINVAL;
     42  1.1  riastrad 	}
     43  1.1  riastrad 
     44  1.1  riastrad 	for (n = 0; n < mem->fake_mappable.size >> PAGE_SHIFT; ++n) {
     45  1.1  riastrad 		ggtt->vm.insert_page(&ggtt->vm,
     46  1.1  riastrad 				     mem->remap_addr + (n << PAGE_SHIFT),
     47  1.1  riastrad 				     n << PAGE_SHIFT,
     48  1.1  riastrad 				     I915_CACHE_NONE, 0);
     49  1.1  riastrad 	}
     50  1.1  riastrad 
     51  1.1  riastrad 	mem->region = (struct resource)DEFINE_RES_MEM(mem->remap_addr,
     52  1.1  riastrad 						      mem->fake_mappable.size);
     53  1.1  riastrad 
     54  1.1  riastrad 	return 0;
     55  1.1  riastrad }
     56  1.1  riastrad 
     57  1.1  riastrad static void release_fake_lmem_bar(struct intel_memory_region *mem)
     58  1.1  riastrad {
     59  1.1  riastrad 	if (!drm_mm_node_allocated(&mem->fake_mappable))
     60  1.1  riastrad 		return;
     61  1.1  riastrad 
     62  1.1  riastrad 	drm_mm_remove_node(&mem->fake_mappable);
     63  1.1  riastrad 
     64  1.1  riastrad 	dma_unmap_resource(&mem->i915->drm.pdev->dev,
     65  1.1  riastrad 			   mem->remap_addr,
     66  1.1  riastrad 			   mem->fake_mappable.size,
     67  1.1  riastrad 			   PCI_DMA_BIDIRECTIONAL,
     68  1.1  riastrad 			   DMA_ATTR_FORCE_CONTIGUOUS);
     69  1.1  riastrad }
     70  1.1  riastrad 
     71  1.1  riastrad static void
     72  1.1  riastrad region_lmem_release(struct intel_memory_region *mem)
     73  1.1  riastrad {
     74  1.1  riastrad 	release_fake_lmem_bar(mem);
     75  1.1  riastrad 	io_mapping_fini(&mem->iomap);
     76  1.1  riastrad 	intel_memory_region_release_buddy(mem);
     77  1.1  riastrad }
     78  1.1  riastrad 
     79  1.1  riastrad static int
     80  1.1  riastrad region_lmem_init(struct intel_memory_region *mem)
     81  1.1  riastrad {
     82  1.1  riastrad 	int ret;
     83  1.1  riastrad 
     84  1.1  riastrad 	if (i915_modparams.fake_lmem_start) {
     85  1.1  riastrad 		ret = init_fake_lmem_bar(mem);
     86  1.1  riastrad 		GEM_BUG_ON(ret);
     87  1.1  riastrad 	}
     88  1.1  riastrad 
     89  1.1  riastrad 	if (!io_mapping_init_wc(&mem->iomap,
     90  1.1  riastrad 				mem->io_start,
     91  1.1  riastrad 				resource_size(&mem->region)))
     92  1.1  riastrad 		return -EIO;
     93  1.1  riastrad 
     94  1.1  riastrad 	ret = intel_memory_region_init_buddy(mem);
     95  1.1  riastrad 	if (ret)
     96  1.1  riastrad 		io_mapping_fini(&mem->iomap);
     97  1.1  riastrad 
     98  1.1  riastrad 	intel_memory_region_set_name(mem, "local");
     99  1.1  riastrad 
    100  1.1  riastrad 	return ret;
    101  1.1  riastrad }
    102  1.1  riastrad 
    103  1.1  riastrad const struct intel_memory_region_ops intel_region_lmem_ops = {
    104  1.1  riastrad 	.init = region_lmem_init,
    105  1.1  riastrad 	.release = region_lmem_release,
    106  1.1  riastrad 	.create_object = __i915_gem_lmem_object_create,
    107  1.1  riastrad };
    108  1.1  riastrad 
    109  1.1  riastrad struct intel_memory_region *
    110  1.1  riastrad intel_setup_fake_lmem(struct drm_i915_private *i915)
    111  1.1  riastrad {
    112  1.1  riastrad 	struct pci_dev *pdev = i915->drm.pdev;
    113  1.1  riastrad 	struct intel_memory_region *mem;
    114  1.1  riastrad 	resource_size_t mappable_end;
    115  1.1  riastrad 	resource_size_t io_start;
    116  1.1  riastrad 	resource_size_t start;
    117  1.1  riastrad 
    118  1.1  riastrad 	GEM_BUG_ON(i915_ggtt_has_aperture(&i915->ggtt));
    119  1.1  riastrad 	GEM_BUG_ON(!i915_modparams.fake_lmem_start);
    120  1.1  riastrad 
    121  1.1  riastrad 	/* Your mappable aperture belongs to me now! */
    122  1.1  riastrad 	mappable_end = pci_resource_len(pdev, 2);
    123  1.1  riastrad 	io_start = pci_resource_start(pdev, 2),
    124  1.1  riastrad 	start = i915_modparams.fake_lmem_start;
    125  1.1  riastrad 
    126  1.1  riastrad 	mem = intel_memory_region_create(i915,
    127  1.1  riastrad 					 start,
    128  1.1  riastrad 					 mappable_end,
    129  1.1  riastrad 					 PAGE_SIZE,
    130  1.1  riastrad 					 io_start,
    131  1.1  riastrad 					 &intel_region_lmem_ops);
    132  1.1  riastrad 	if (!IS_ERR(mem)) {
    133  1.1  riastrad 		drm_info(&i915->drm, "Intel graphics fake LMEM: %pR\n",
    134  1.1  riastrad 			 &mem->region);
    135  1.1  riastrad 		drm_info(&i915->drm,
    136  1.1  riastrad 			 "Intel graphics fake LMEM IO start: %llx\n",
    137  1.1  riastrad 			(u64)mem->io_start);
    138  1.1  riastrad 		drm_info(&i915->drm, "Intel graphics fake LMEM size: %llx\n",
    139  1.1  riastrad 			 (u64)resource_size(&mem->region));
    140  1.1  riastrad 	}
    141  1.1  riastrad 
    142  1.1  riastrad 	return mem;
    143  1.1  riastrad }
    144