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