Index | Thread | Search

From:
Jonathan Gray <jsg@jsg.id.au>
Subject:
Re: [PATCH 0/4] i915 dg2 patches
To:
kisekinopureya <kisekinopureya@disroot.org>
Cc:
tech@openbsd.org
Date:
Fri, 11 Sep 2026 15:59:39 +1000

Download raw body.

Thread
On Thu, Sep 10, 2026 at 10:13:48PM +0300, kisekinopureya wrote:
> This patch series adds necessary changes to i915 for Intel Arc (DG2).
> I've been using it for a week on -current and haven't observed any
> panic/crashes yet. I don't have an integrated gpu, i can't confirm
> whether the changes broke integrated gpus.
> 
> This is my first patch to the mailing list, please let me know 
> if I need to adjust anything.
> 
> dmesg
> ...
> inteldrm0: msi, DG2, gen 12
> inteldrm0: 1920x1080, 32bpp
> wsdisplay0 at inteldrm0 mux 1: console (std, vt100 emulation), using wskbd0
> inteldrm0 at pci3 dev 0 function 0 "Intel Arc A770" rev 0x08
> drm0 at inteldrm0
> ...
> 
> glxinfo -B
> ...
> direct rendering: Yes
> Extended renderer info (GLX_MESA_query_renderer):
>     Vendor: Intel (0x8086)
>     Device: Mesa Intel(R) Arc(tm) A770 Graphics (DG2) (0x56a0)
>     Version: 25.0.7
>     Accelerated: yes
> ...
> 
> 
> kisekinopureya (4):
>   remove force_probe for dg2
>   unstub intel_slicemask_from_xehp_dssmask
>   disable huc for dg2
>   port gem and ttm memory management to uvm

Disabling HuC to avoid MEI is interesting.

For comparison, here is a diff from one of my dg2 branches from a few
months ago.  I don't remember the state, I suspect there were problems
initialising GuC or with MEI.

Needs dma_tag_lookup() change I committed earlier today.

diff --git sys/dev/pci/drm/drm_linux.c sys/dev/pci/drm/drm_linux.c
index 53a6efd90e2..3405463a620 100644
--- sys/dev/pci/drm/drm_linux.c
+++ sys/dev/pci/drm/drm_linux.c
@@ -3487,6 +3487,37 @@ dma_unmap_resource(struct device *dev, dma_addr_t addr, size_t size,
 	STUB();
 }
 
+int
+dma_map_sgtable(struct device *dev, struct sg_table *sgt,
+    enum dma_data_direction dir, unsigned long attrs)
+{
+	bus_dma_tag_t dmat = dma_tag_lookup(dev);
+	bus_dma_segment_t seg;
+	int error, i;
+	struct scatterlist *sg;
+
+	error = bus_dmamap_create(dmat, sgt->sgl->length, sgt->nents,
+	    sgt->sgl->length, 0, BUS_DMA_WAITOK, &sgt->dmamap);
+	if (error)
+		return -ENOMEM;
+
+	sgt->dmamap->dm_mapsize = 0;
+	sgt->dmamap->dm_nsegs = 0;
+	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+		sgt->dmamap->dm_segs[i].ds_addr = VM_PAGE_TO_PHYS(sg->__page);
+		sgt->dmamap->dm_segs[i].ds_len = sgt->sgl->length;
+		sgt->dmamap->dm_nsegs++;
+		sgt->dmamap->dm_mapsize += sgt->sgl->length;
+	}
+	sgt->dmamap->dm_nsegs = sgt->nents;
+	error = bus_dmamap_load_raw(dmat, sgt->dmamap, sgt->dmamap->dm_segs,
+	    sgt->dmamap->dm_nsegs, sgt->dmamap->dm_mapsize, BUS_DMA_WAITOK);
+	if (error)
+		return -ENOMEM;
+
+	return 0;
+}
+
 #ifdef BUS_DMA_FIXED
 
 #include <linux/iommu.h>
diff --git sys/dev/pci/drm/i915/gem/i915_gem_object.h sys/dev/pci/drm/i915/gem/i915_gem_object.h
index b266814d3fb..0fb18d0aa43 100644
--- sys/dev/pci/drm/i915/gem/i915_gem_object.h
+++ sys/dev/pci/drm/i915/gem/i915_gem_object.h
@@ -855,10 +855,10 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
 			 size_t size, struct intel_memory_region *mr,
 			 struct address_space *mapping,
 			 unsigned int max_segment,
-			 struct drm_i915_gem_object *obj);
+			 struct uvm_object *);
 void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
 			 bool dirty, bool backup,
-			 struct drm_i915_gem_object *obj);
+			 struct uvm_object *, size_t);
 #endif
 void __shmem_writeback(size_t size, struct address_space *mapping);
 
diff --git sys/dev/pci/drm/i915/gem/i915_gem_shmem.c sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
index ee8034c9c63..970b47f8fd6 100644
--- sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
+++ sys/dev/pci/drm/i915/gem/i915_gem_shmem.c
@@ -34,7 +34,7 @@ static void check_release_folio_batch(struct folio_batch *fbatch)
 
 void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
 			 bool dirty, bool backup,
-			 struct drm_i915_gem_object *obj)
+			 struct uvm_object *uao, size_t uao_size)
 {
 	struct sgt_iter sgt_iter;
 	struct folio_batch fbatch;
@@ -69,7 +69,7 @@ void shmem_sg_free_table(struct sg_table *st, struct address_space *mapping,
 	if (fbatch.nr)
 		check_release_folio_batch(&fbatch);
 #else
-	uvm_obj_unwire(obj->base.uao, 0, obj->base.size);
+	uvm_obj_unwire(uao, 0, uao_size);
 #endif
 
 	sg_free_table(st);
@@ -79,7 +79,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
 			 size_t size, struct intel_memory_region *mr,
 			 struct address_space *mapping,
 			 unsigned int max_segment,
-			 struct drm_i915_gem_object *obj)
+			 struct uvm_object *uao)
 {
 	unsigned int page_count; /* restricted by sg_alloc_table */
 	unsigned long i;
@@ -201,7 +201,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
 	st->nents = 0;
 
 	TAILQ_INIT(&plist);
-	if (uvm_obj_wire(obj->base.uao, 0, obj->base.size, &plist)) {
+	if (uvm_obj_wire(uao, 0, size, &plist)) {
 		ret = -ENOMEM;
 		goto err_sg;
 	}
@@ -225,7 +225,7 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st,
 err_sg:
 	sg_mark_end(sg);
 	if (sg != st->sgl) {
-		shmem_sg_free_table(st, mapping, false, false, obj);
+		shmem_sg_free_table(st, mapping, false, false, uao, size);
 	} else {
 		mapping_clear_unevictable(mapping);
 		sg_free_table(st);
@@ -275,7 +275,7 @@ rebuild_st:
 				   max_segment);
 #else
 	ret = shmem_sg_alloc_table(i915, st, obj->base.size, mem, NULL,
-				   max_segment, obj);
+				   max_segment, obj->base.uao);
 #endif
 	if (ret)
 		goto err_st;
@@ -291,7 +291,7 @@ rebuild_st:
 #ifdef __linux__
 			shmem_sg_free_table(st, mapping, false, false);
 #else
-			shmem_sg_free_table(st, NULL, false, false, obj);
+			shmem_sg_free_table(st, NULL, false, false, obj->base.uao, obj->base.size);
 #endif
 			sg_free_table(st);
 			kfree(st);
@@ -320,7 +320,7 @@ err_pages:
 #ifdef __linux__
 	shmem_sg_free_table(st, mapping, false, false);
 #else
-	shmem_sg_free_table(st, NULL, false, false, obj);
+	shmem_sg_free_table(st, NULL, false, false, obj->base.uao, obj->base.size);
 #endif
 	/*
 	 * shmemfs first checks if there is enough memory to allocate the page
@@ -459,7 +459,8 @@ void i915_gem_object_put_pages_shmem(struct drm_i915_gem_object *obj, struct sg_
 			    obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED);
 #else
 	shmem_sg_free_table(pages, NULL,
-			    obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED, obj);
+			    obj->mm.dirty, obj->mm.madv == I915_MADV_WILLNEED,
+			    obj->base.uao, obj->base.size);
 #endif
 	kfree(pages);
 	obj->mm.dirty = false;
diff --git sys/dev/pci/drm/i915/gem/i915_gem_ttm.c sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
index 570d0971fd4..00c4b9768b4 100644
--- sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
+++ sys/dev/pci/drm/i915/gem/i915_gem_ttm.c
@@ -53,7 +53,11 @@ struct i915_ttm_tt {
 	struct i915_refct_sgt cached_rsgt;
 
 	bool is_shmem;
+#ifdef __linux__
 	struct file *filp;
+#else
+	struct uvm_object *filp;
+#endif
 };
 
 static const struct ttm_place sys_placement_flags = {
@@ -179,13 +183,11 @@ i915_ttm_placement_from_obj(const struct drm_i915_gem_object *obj,
 	placement->placement = places;
 }
 
+#ifdef __linux__
 static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
 				      struct ttm_tt *ttm,
 				      struct ttm_operation_ctx *ctx)
 {
-	STUB();
-	return -ENOSYS;
-#ifdef notyet
 	struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev);
 	struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM];
 	struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
@@ -239,8 +241,58 @@ err_free_st:
 	shmem_sg_free_table(st, filp->f_mapping, false, false);
 
 	return err;
-#endif
 }
+#else /* !__linux__ */
+static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
+				      struct ttm_tt *ttm,
+				      struct ttm_operation_ctx *ctx)
+{
+	struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev);
+	struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM];
+	struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
+	const unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
+	const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT;
+	struct uvm_object *uao = i915_tt->filp;
+	struct sgt_iter sgt_iter;
+	struct sg_table *st;
+	struct vm_page *page;
+	unsigned long i;
+	int err;
+
+	if (!uao) {
+		uao = uao_create(size, 0);
+		if (uao == NULL)
+			return -ENOMEM;
+
+		i915_tt->filp = uao;
+	}
+
+	st = &i915_tt->cached_rsgt.table;
+	err = shmem_sg_alloc_table(i915, st, size, mr, /*filp->f_mapping*/NULL,
+				   max_segment, uao);
+	if (err)
+		return err;
+
+	err = dma_map_sgtable(i915_tt->dev, st, DMA_BIDIRECTIONAL,
+			      DMA_ATTR_SKIP_CPU_SYNC);
+	if (err)
+		goto err_free_st;
+
+	i = 0;
+	for_each_sgt_page(page, sgt_iter, st)
+		ttm->pages[i++] = page;
+
+	if (ttm->page_flags & TTM_TT_FLAG_SWAPPED)
+		ttm->page_flags &= ~TTM_TT_FLAG_SWAPPED;
+
+	return 0;
+
+err_free_st:
+	shmem_sg_free_table(st, NULL, false, false, uao, size);
+
+	return err;
+}
+#endif /* !__linux__ */
 
 static void i915_ttm_tt_shmem_unpopulate(struct ttm_tt *ttm)
 {
@@ -356,7 +408,11 @@ static void i915_ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
 	struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
 
 	if (i915_tt->filp)
+#ifdef __linux__
 		fput(i915_tt->filp);
+#else
+		uao_detach(i915_tt->filp);
+#endif
 
 	ttm_tt_fini(ttm);
 	i915_refct_sgt_put(&i915_tt->cached_rsgt);
@@ -456,13 +512,14 @@ int i915_ttm_purge(struct drm_i915_gem_object *obj)
 #ifdef __linux__
 			shmem_truncate_range(file_inode(i915_tt->filp),
 					     0, (loff_t)-1);
+			fput(fetch_and_zero(&i915_tt->filp));
 #else
 			rw_enter(obj->base.uao->vmobjlock, RW_WRITE);
 			obj->base.uao->pgops->pgo_flush(obj->base.uao, 0,
 			    obj->base.size, PGO_ALLPAGES | PGO_FREE);
 			rw_exit(obj->base.uao->vmobjlock);
+			uao_detach(fetch_and_zero(&i915_tt->filp));
 #endif
-			fput(fetch_and_zero(&i915_tt->filp));
 		}
 	}
 
diff --git sys/dev/pci/drm/i915/gt/uc/intel_guc_fw.c sys/dev/pci/drm/i915/gt/uc/intel_guc_fw.c
index b1bda1b84f0..7847c374690 100644
--- sys/dev/pci/drm/i915/gt/uc/intel_guc_fw.c
+++ sys/dev/pci/drm/i915/gt/uc/intel_guc_fw.c
@@ -158,7 +158,7 @@ static inline bool guc_load_done(struct intel_uncore *uncore, u32 *status, bool
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
 #define GUC_LOAD_RETRY_LIMIT	20
 #else
-#define GUC_LOAD_RETRY_LIMIT	3
+#define GUC_LOAD_RETRY_LIMIT	20
 #endif
 
 static int guc_wait_ucode(struct intel_guc *guc)
diff --git sys/dev/pci/drm/i915/i915_pci.c sys/dev/pci/drm/i915/i915_pci.c
index 2f30756ac4a..ce56d2ea89f 100644
--- sys/dev/pci/drm/i915/i915_pci.c
+++ sys/dev/pci/drm/i915/i915_pci.c
@@ -738,7 +738,6 @@ static const struct intel_device_info adl_p_info = {
 
 static const struct intel_device_info dg2_info = {
 	DG2_FEATURES,
-	.require_force_probe = 1,
 };
 
 static const struct intel_device_info ats_m_info = {