1 // SPDX-License-Identifier: MIT
3 * Copyright © 2019 Intel Corporation
7 #include "intel_memory_region.h"
8 #include "gem/i915_gem_lmem.h"
9 #include "gem/i915_gem_region.h"
10 #include "intel_region_lmem.h"
12 static int init_fake_lmem_bar(struct intel_memory_region
*mem
)
14 struct drm_i915_private
*i915
= mem
->i915
;
15 struct i915_ggtt
*ggtt
= &i915
->ggtt
;
19 /* We want to 1:1 map the mappable aperture to our reserved region */
21 mem
->fake_mappable
.start
= 0;
22 mem
->fake_mappable
.size
= resource_size(&mem
->region
);
23 mem
->fake_mappable
.color
= I915_COLOR_UNEVICTABLE
;
25 ret
= drm_mm_reserve_node(&ggtt
->vm
.mm
, &mem
->fake_mappable
);
29 mem
->remap_addr
= dma_map_resource(&i915
->drm
.pdev
->dev
,
31 mem
->fake_mappable
.size
,
32 PCI_DMA_BIDIRECTIONAL
,
33 DMA_ATTR_FORCE_CONTIGUOUS
);
34 if (dma_mapping_error(&i915
->drm
.pdev
->dev
, mem
->remap_addr
)) {
35 drm_mm_remove_node(&mem
->fake_mappable
);
39 for (n
= 0; n
< mem
->fake_mappable
.size
>> PAGE_SHIFT
; ++n
) {
40 ggtt
->vm
.insert_page(&ggtt
->vm
,
41 mem
->remap_addr
+ (n
<< PAGE_SHIFT
),
46 mem
->region
= (struct resource
)DEFINE_RES_MEM(mem
->remap_addr
,
47 mem
->fake_mappable
.size
);
52 static void release_fake_lmem_bar(struct intel_memory_region
*mem
)
54 if (!drm_mm_node_allocated(&mem
->fake_mappable
))
57 drm_mm_remove_node(&mem
->fake_mappable
);
59 dma_unmap_resource(&mem
->i915
->drm
.pdev
->dev
,
61 mem
->fake_mappable
.size
,
62 PCI_DMA_BIDIRECTIONAL
,
63 DMA_ATTR_FORCE_CONTIGUOUS
);
67 region_lmem_release(struct intel_memory_region
*mem
)
69 release_fake_lmem_bar(mem
);
70 io_mapping_fini(&mem
->iomap
);
71 intel_memory_region_release_buddy(mem
);
75 region_lmem_init(struct intel_memory_region
*mem
)
79 if (mem
->i915
->params
.fake_lmem_start
) {
80 ret
= init_fake_lmem_bar(mem
);
84 if (!io_mapping_init_wc(&mem
->iomap
,
86 resource_size(&mem
->region
)))
89 ret
= intel_memory_region_init_buddy(mem
);
91 io_mapping_fini(&mem
->iomap
);
93 intel_memory_region_set_name(mem
, "local");
98 const struct intel_memory_region_ops intel_region_lmem_ops
= {
99 .init
= region_lmem_init
,
100 .release
= region_lmem_release
,
101 .create_object
= __i915_gem_lmem_object_create
,
104 struct intel_memory_region
*
105 intel_setup_fake_lmem(struct drm_i915_private
*i915
)
107 struct pci_dev
*pdev
= i915
->drm
.pdev
;
108 struct intel_memory_region
*mem
;
109 resource_size_t mappable_end
;
110 resource_size_t io_start
;
111 resource_size_t start
;
113 GEM_BUG_ON(i915_ggtt_has_aperture(&i915
->ggtt
));
114 GEM_BUG_ON(!i915
->params
.fake_lmem_start
);
116 /* Your mappable aperture belongs to me now! */
117 mappable_end
= pci_resource_len(pdev
, 2);
118 io_start
= pci_resource_start(pdev
, 2),
119 start
= i915
->params
.fake_lmem_start
;
121 mem
= intel_memory_region_create(i915
,
126 &intel_region_lmem_ops
);
128 drm_info(&i915
->drm
, "Intel graphics fake LMEM: %pR\n",
131 "Intel graphics fake LMEM IO start: %llx\n",
133 drm_info(&i915
->drm
, "Intel graphics fake LMEM size: %llx\n",
134 (u64
)resource_size(&mem
->region
));