Index | Thread | Search

From:
Jonathan Gray <jsg@jsg.id.au>
Subject:
Re: radeondrm: fix CAFEDEAD failure during boot for old Radeons
To:
Ted Bullock <tbullock@comlore.com>
Cc:
tech@openbsd.org
Date:
Thu, 8 Oct 2026 19:44:09 +1100

Download raw body.

Thread
On Thu, Oct 08, 2026 at 12:24:06AM -0600, Ted Bullock wrote:
> Hello,
> 
> I think this is a plausible fix for a very longstanding bug with
> regards to older Radeon GPUs on a variety of platforms.
> 
> The telltale dmesg line looks something like
> [drm] *ERROR* radeon: ring test failed (scratch(0x15E4)=0xCAFEDEAD)
> 
> https://marc.info/?l=openbsd-bugs&m=162447131102854
> https://marc.info/?l=openbsd-bugs&m=177938265735653
> https://marc.info/?l=openbsd-misc&m=155873575216626&w=2
> 
> The call to the stubbed linux dma selection logic in
> dma_addressing_limited() has been removed (always false), but according
> to radeon_device.c, the older Radeon chips should be using the driver's
> 32 bit DMA logic.
> 
> 	/* set DMA mask.
> 	 * PCIE - can handle 40-bits.
> 	 * IGP - can handle 40-bits
> 	 * AGP - generally dma32 is safest
> 	 * PCI - dma32 for legacy pci gart, 40 bits on newer asics
> 	 */
> 	dma_bits = 40;
> 	if (rdev->flags & RADEON_IS_AGP)
> 		dma_bits = 32;
> 	if ((rdev->flags & RADEON_IS_PCI) &&
> 	    (rdev->family <= CHIP_RS740))
> 		dma_bits = 32;
> #ifdef CONFIG_PPC64
> 	if (rdev->family == CHIP_CEDAR)
> 		dma_bits = 32;
> #endif
> 
> I have no idea about the PPC64 flag, nor do I have one of those fancy
> Talos machines to play around with. Since AGP is disabled by default
> for this driver, I'm speculating we can just use the PCI logic in lieu
> of the dma_addressing_limited() function.
> 
> I can confirm that my Sun Blade 100 with the XVR-100 finally boots
> without the CAFEDEAD warning in dmesg, and it also lets me enable
> accelerated X.
> 
> Ted

The Linux documentation for dma_addressing_limited() describes it as a
test against the amount of physical memory.

The Linux function arguments are awkward to derive other types from,
so here is a radeon specific alternative.

Index: sys/dev/pci/drm/radeon/radeon.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/radeon/radeon.h,v
diff -u -p -r1.33 radeon.h
--- sys/dev/pci/drm/radeon/radeon.h	9 Mar 2026 23:58:03 -0000	1.33
+++ sys/dev/pci/drm/radeon/radeon.h	8 Oct 2026 08:22:09 -0000
@@ -2326,6 +2326,7 @@ struct radeon_device {
 	bus_space_tag_t			memt;
 	bus_dma_tag_t			dmat;
 	void				*irqh;
+	bool				dma_limited;
 
 	void				(*switchcb)(void *, int, int);
 	void				*switchcbarg;
Index: sys/dev/pci/drm/radeon/radeon_device.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/radeon/radeon_device.c,v
diff -u -p -r1.34 radeon_device.c
--- sys/dev/pci/drm/radeon/radeon_device.c	5 Oct 2026 08:14:58 -0000	1.34
+++ sys/dev/pci/drm/radeon/radeon_device.c	8 Oct 2026 08:25:35 -0000
@@ -1392,6 +1392,9 @@ int radeon_device_init(struct radeon_dev
 	}
 	rdev->need_swiotlb = drm_need_swiotlb(dma_bits);
 
+	if (ptoa(physmem) > (1ULL << dma_bits))
+		rdev->dma_limited = true;
+
 	/* Registers mapping */
 	/* TODO: block userspace mapping of io register */
 	mtx_init(&rdev->mmio_idx_lock, IPL_TTY);
Index: sys/dev/pci/drm/radeon/radeon_ttm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/radeon/radeon_ttm.c,v
diff -u -p -r1.28 radeon_ttm.c
--- sys/dev/pci/drm/radeon/radeon_ttm.c	9 Mar 2026 23:58:03 -0000	1.28
+++ sys/dev/pci/drm/radeon/radeon_ttm.c	8 Oct 2026 08:29:30 -0000
@@ -717,7 +717,7 @@ int radeon_ttm_init(struct radeon_device
 			       /*rdev_to_drm(rdev)->anon_inode->i_mapping*/NULL,
 			       rdev_to_drm(rdev)->vma_offset_manager,
 			       rdev->need_swiotlb,
-			       dma_addressing_limited(&rdev->pdev->dev));
+			       rdev->dma_limited);
 #endif
 	if (r) {
 		DRM_ERROR("failed initializing buffer object driver(%d).\n", r);