intel_region_lmem.c 4.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// 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"

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
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;

29
	mem->remap_addr = dma_map_resource(i915->drm.dev,
30 31 32 33
					   mem->region.start,
					   mem->fake_mappable.size,
					   PCI_DMA_BIDIRECTIONAL,
					   DMA_ATTR_FORCE_CONTIGUOUS);
34
	if (dma_mapping_error(i915->drm.dev, mem->remap_addr)) {
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
		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)
{
54 55 56 57
	if (!drm_mm_node_allocated(&mem->fake_mappable))
		return;

	drm_mm_remove_node(&mem->fake_mappable);
58

59
	dma_unmap_resource(mem->i915->drm.dev,
60 61 62 63 64 65
			   mem->remap_addr,
			   mem->fake_mappable.size,
			   PCI_DMA_BIDIRECTIONAL,
			   DMA_ATTR_FORCE_CONTIGUOUS);
}

66 67 68
static void
region_lmem_release(struct intel_memory_region *mem)
{
69
	release_fake_lmem_bar(mem);
70 71 72 73 74 75 76 77 78
	io_mapping_fini(&mem->iomap);
	intel_memory_region_release_buddy(mem);
}

static int
region_lmem_init(struct intel_memory_region *mem)
{
	int ret;

79
	if (mem->i915->params.fake_lmem_start) {
80 81 82 83
		ret = init_fake_lmem_bar(mem);
		GEM_BUG_ON(ret);
	}

84 85 86 87 88 89 90 91 92
	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);

93 94
	intel_memory_region_set_name(mem, "local");

95 96 97
	return ret;
}

98
static const struct intel_memory_region_ops intel_region_lmem_ops = {
99 100
	.init = region_lmem_init,
	.release = region_lmem_release,
101
	.init_object = __i915_gem_lmem_object_init,
102
};
103 104

struct intel_memory_region *
105
intel_gt_setup_fake_lmem(struct intel_gt *gt)
106
{
107
	struct drm_i915_private *i915 = gt->i915;
108
	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
109 110 111 112 113
	struct intel_memory_region *mem;
	resource_size_t mappable_end;
	resource_size_t io_start;
	resource_size_t start;

114 115 116 117 118 119
	if (!HAS_LMEM(i915))
		return ERR_PTR(-ENODEV);

	if (!i915->params.fake_lmem_start)
		return ERR_PTR(-ENODEV);

120 121 122 123
	GEM_BUG_ON(i915_ggtt_has_aperture(&i915->ggtt));

	/* Your mappable aperture belongs to me now! */
	mappable_end = pci_resource_len(pdev, 2);
124
	io_start = pci_resource_start(pdev, 2);
125
	start = i915->params.fake_lmem_start;
126 127 128 129 130 131 132 133

	mem = intel_memory_region_create(i915,
					 start,
					 mappable_end,
					 PAGE_SIZE,
					 io_start,
					 &intel_region_lmem_ops);
	if (!IS_ERR(mem)) {
134 135 136 137 138 139
		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",
140 141 142 143 144
			 (u64)resource_size(&mem->region));
	}

	return mem;
}
M
Matthew Auld 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180

static struct intel_memory_region *setup_lmem(struct intel_gt *gt)
{
	struct drm_i915_private *i915 = gt->i915;
	struct pci_dev *pdev = i915->drm.pdev;
	struct intel_memory_region *mem;
	resource_size_t io_start;
	resource_size_t size;

	if (!IS_DGFX(i915))
		return ERR_PTR(-ENODEV);

	io_start = pci_resource_start(pdev, 2);
	size = pci_resource_len(pdev, 2);

	mem = intel_memory_region_create(i915,
					 0,
					 size,
					 I915_GTT_PAGE_SIZE_4K,
					 io_start,
					 &intel_region_lmem_ops);
	if (IS_ERR(mem))
		return mem;

	drm_dbg(&i915->drm, "Local memory: %pR\n", &mem->region);
	drm_dbg(&i915->drm, "Local memory IO start: %pa\n",
		&mem->io_start);
	drm_info(&i915->drm, "Local memory available: %pa\n", &size);

	return mem;
}

struct intel_memory_region *intel_gt_setup_lmem(struct intel_gt *gt)
{
	return setup_lmem(gt);
}