Skip to content

Commit 1629224

Browse files
matt-auldickle
authored andcommitted
drm/i915/lmem: add the fake lmem region
Intended for upstream testing so that we can still exercise the LMEM plumbing and !i915_ggtt_has_aperture paths. Smoke tested on Skull Canyon device. This works by allocating an intel_memory_region for a reserved portion of system memory, which we treat like LMEM. For the LMEMBAR we steal the aperture and 1:1 it map to the stolen region. To enable simply set the i915 modparam fake_lmem_start= on the kernel cmdline with the start of reserved region(see memmap=). The size of the region we can use is determined by the size of the mappable aperture, so the size of reserved region should be >= mappable_end. For now we only enable for the selftests. Depends on CONFIG_DRM_I915_UNSTABLE being enabled. eg. memmap=2G$16G i915.fake_lmem_start=0x400000000 v2: make fake_lmem_start an i915 modparam Signed-off-by: Matthew Auld <[email protected]> Cc: Joonas Lahtinen <[email protected]> Cc: Abdiel Janulgue <[email protected]> Cc: Arkadiusz Hiler <[email protected]> Cc: Chris Wilson <[email protected]> Reviewed-by: Chris Wilson <[email protected]> Signed-off-by: Chris Wilson <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 4974826 commit 1629224

File tree

9 files changed

+140
-0
lines changed

9 files changed

+140
-0
lines changed

drivers/gpu/drm/i915/Kconfig.unstable

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,11 @@ config DRM_I915_UNSTABLE
1919
Recommended for driver developers _only_.
2020

2121
If in the slightest bit of doubt, say "N".
22+
23+
config DRM_I915_UNSTABLE_FAKE_LMEM
24+
bool "Enable the experimental fake lmem"
25+
depends on DRM_I915_UNSTABLE
26+
default n
27+
help
28+
Convert some system memory into a fake local memory region for
29+
testing.

drivers/gpu/drm/i915/gem/i915_gem_lmem.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ i915_gem_object_lmem_io_map_page(struct drm_i915_gem_object *obj,
2424
resource_size_t offset;
2525

2626
offset = i915_gem_object_get_dma_address(obj, n);
27+
offset -= obj->mm.region->region.start;
2728

2829
return io_mapping_map_wc(&obj->mm.region->iomap, offset, PAGE_SIZE);
2930
}
@@ -35,6 +36,7 @@ i915_gem_object_lmem_io_map_page_atomic(struct drm_i915_gem_object *obj,
3536
resource_size_t offset;
3637

3738
offset = i915_gem_object_get_dma_address(obj, n);
39+
offset -= obj->mm.region->region.start;
3840

3941
return io_mapping_map_atomic_wc(&obj->mm.region->iomap, offset);
4042
}
@@ -49,6 +51,7 @@ i915_gem_object_lmem_io_map(struct drm_i915_gem_object *obj,
4951
GEM_BUG_ON(!i915_gem_object_is_contiguous(obj));
5052

5153
offset = i915_gem_object_get_dma_address(obj, n);
54+
offset -= obj->mm.region->region.start;
5255

5356
return io_mapping_map_wc(&obj->mm.region->iomap, offset, size);
5457
}

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,21 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14831483
if (!i915_modparams.nuclear_pageflip && match_info->gen < 5)
14841484
dev_priv->drm.driver_features &= ~DRIVER_ATOMIC;
14851485

1486+
/*
1487+
* Check if we support fake LMEM -- for now we only unleash this for
1488+
* the live selftests(test-and-exit).
1489+
*/
1490+
if (IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM)) {
1491+
if (INTEL_GEN(dev_priv) >= 9 && i915_selftest.live < 0 &&
1492+
i915_modparams.fake_lmem_start) {
1493+
mkwrite_device_info(dev_priv)->memory_regions =
1494+
REGION_SMEM | REGION_LMEM | REGION_STOLEN;
1495+
mkwrite_device_info(dev_priv)->is_dgfx = true;
1496+
GEM_BUG_ON(!HAS_LMEM(dev_priv));
1497+
GEM_BUG_ON(!IS_DGFX(dev_priv));
1498+
}
1499+
}
1500+
14861501
ret = pci_enable_device(pdev);
14871502
if (ret)
14881503
goto out_fini;

drivers/gpu/drm/i915/i915_params.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ i915_param_named(enable_gvt, bool, 0400,
179179
"Enable support for Intel GVT-g graphics virtualization host support(default:false)");
180180
#endif
181181

182+
#if IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM)
183+
i915_param_named_unsafe(fake_lmem_start, ulong, 0600,
184+
"Fake LMEM start offset (default: 0)");
185+
#endif
186+
182187
static __always_inline void _print_param(struct drm_printer *p,
183188
const char *name,
184189
const char *type,
@@ -190,6 +195,8 @@ static __always_inline void _print_param(struct drm_printer *p,
190195
drm_printf(p, "i915.%s=%d\n", name, *(const int *)x);
191196
else if (!__builtin_strcmp(type, "unsigned int"))
192197
drm_printf(p, "i915.%s=%u\n", name, *(const unsigned int *)x);
198+
else if (!__builtin_strcmp(type, "unsigned long"))
199+
drm_printf(p, "i915.%s=%lu\n", name, *(const unsigned long *)x);
193200
else if (!__builtin_strcmp(type, "char *"))
194201
drm_printf(p, "i915.%s=%s\n", name, *(const char **)x);
195202
else

drivers/gpu/drm/i915/i915_params.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct drm_printer;
6666
param(int, fastboot, -1) \
6767
param(int, enable_dpcd_backlight, 0) \
6868
param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE) \
69+
param(unsigned long, fake_lmem_start, 0) \
6970
/* leave bools at the end to not create holes */ \
7071
param(bool, alpha_support, IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT)) \
7172
param(bool, enable_hangcheck, true) \

drivers/gpu/drm/i915/intel_memory_region.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,9 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
228228
case INTEL_MEMORY_STOLEN:
229229
mem = i915_gem_stolen_setup(i915);
230230
break;
231+
case INTEL_MEMORY_LOCAL:
232+
mem = intel_setup_fake_lmem(i915);
233+
break;
231234
}
232235

233236
if (IS_ERR(mem)) {

drivers/gpu/drm/i915/intel_memory_region.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/ioport.h>
1111
#include <linux/mutex.h>
1212
#include <linux/io-mapping.h>
13+
#include <drm/drm_mm.h>
1314

1415
#include "i915_buddy.h"
1516

@@ -71,6 +72,9 @@ struct intel_memory_region {
7172
struct io_mapping iomap;
7273
struct resource region;
7374

75+
/* For fake LMEM */
76+
struct drm_mm_node fake_mappable;
77+
7478
struct i915_buddy_mm mm;
7579
struct mutex mm_lock;
7680

@@ -83,6 +87,8 @@ struct intel_memory_region {
8387
unsigned int instance;
8488
unsigned int id;
8589

90+
dma_addr_t remap_addr;
91+
8692
struct {
8793
struct mutex lock; /* Protects access to objects */
8894
struct list_head list;

drivers/gpu/drm/i915/intel_region_lmem.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,62 @@
99
#include "gem/i915_gem_region.h"
1010
#include "intel_region_lmem.h"
1111

12+
static int init_fake_lmem_bar(struct intel_memory_region *mem)
13+
{
14+
struct drm_i915_private *i915 = mem->i915;
15+
struct i915_ggtt *ggtt = &i915->ggtt;
16+
unsigned long n;
17+
int ret;
18+
19+
/* We want to 1:1 map the mappable aperture to our reserved region */
20+
21+
mem->fake_mappable.start = 0;
22+
mem->fake_mappable.size = resource_size(&mem->region);
23+
mem->fake_mappable.color = I915_COLOR_UNEVICTABLE;
24+
25+
ret = drm_mm_reserve_node(&ggtt->vm.mm, &mem->fake_mappable);
26+
if (ret)
27+
return ret;
28+
29+
mem->remap_addr = dma_map_resource(&i915->drm.pdev->dev,
30+
mem->region.start,
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);
36+
return -EINVAL;
37+
}
38+
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),
42+
n << PAGE_SHIFT,
43+
I915_CACHE_NONE, 0);
44+
}
45+
46+
mem->region = (struct resource)DEFINE_RES_MEM(mem->remap_addr,
47+
mem->fake_mappable.size);
48+
49+
return 0;
50+
}
51+
52+
static void release_fake_lmem_bar(struct intel_memory_region *mem)
53+
{
54+
if (drm_mm_node_allocated(&mem->fake_mappable))
55+
drm_mm_remove_node(&mem->fake_mappable);
56+
57+
dma_unmap_resource(&mem->i915->drm.pdev->dev,
58+
mem->remap_addr,
59+
mem->fake_mappable.size,
60+
PCI_DMA_BIDIRECTIONAL,
61+
DMA_ATTR_FORCE_CONTIGUOUS);
62+
}
63+
1264
static void
1365
region_lmem_release(struct intel_memory_region *mem)
1466
{
67+
release_fake_lmem_bar(mem);
1568
io_mapping_fini(&mem->iomap);
1669
intel_memory_region_release_buddy(mem);
1770
}
@@ -21,6 +74,11 @@ region_lmem_init(struct intel_memory_region *mem)
2174
{
2275
int ret;
2376

77+
if (i915_modparams.fake_lmem_start) {
78+
ret = init_fake_lmem_bar(mem);
79+
GEM_BUG_ON(ret);
80+
}
81+
2482
if (!io_mapping_init_wc(&mem->iomap,
2583
mem->io_start,
2684
resource_size(&mem->region)))
@@ -38,3 +96,37 @@ const struct intel_memory_region_ops intel_region_lmem_ops = {
3896
.release = region_lmem_release,
3997
.create_object = __i915_gem_lmem_object_create,
4098
};
99+
100+
struct intel_memory_region *
101+
intel_setup_fake_lmem(struct drm_i915_private *i915)
102+
{
103+
struct pci_dev *pdev = i915->drm.pdev;
104+
struct intel_memory_region *mem;
105+
resource_size_t mappable_end;
106+
resource_size_t io_start;
107+
resource_size_t start;
108+
109+
GEM_BUG_ON(i915_ggtt_has_aperture(&i915->ggtt));
110+
GEM_BUG_ON(!i915_modparams.fake_lmem_start);
111+
112+
/* Your mappable aperture belongs to me now! */
113+
mappable_end = pci_resource_len(pdev, 2);
114+
io_start = pci_resource_start(pdev, 2),
115+
start = i915_modparams.fake_lmem_start;
116+
117+
mem = intel_memory_region_create(i915,
118+
start,
119+
mappable_end,
120+
PAGE_SIZE,
121+
io_start,
122+
&intel_region_lmem_ops);
123+
if (!IS_ERR(mem)) {
124+
DRM_INFO("Intel graphics fake LMEM: %pR\n", &mem->region);
125+
DRM_INFO("Intel graphics fake LMEM IO start: %llx\n",
126+
(u64)mem->io_start);
127+
DRM_INFO("Intel graphics fake LMEM size: %llx\n",
128+
(u64)resource_size(&mem->region));
129+
}
130+
131+
return mem;
132+
}

drivers/gpu/drm/i915/intel_region_lmem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
#ifndef __INTEL_REGION_LMEM_H
77
#define __INTEL_REGION_LMEM_H
88

9+
struct drm_i915_private;
10+
911
extern const struct intel_memory_region_ops intel_region_lmem_ops;
1012

13+
struct intel_memory_region *
14+
intel_setup_fake_lmem(struct drm_i915_private *i915);
15+
1116
#endif /* !__INTEL_REGION_LMEM_H */

0 commit comments

Comments
 (0)