Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -4259,7 +4259,15 @@ int amdgpu_device_init(struct amdgpu_device *adev,
PCI_EXP_DEVCAP2_ATOMIC_COMP64);
}
#elif defined(__FreeBSD__)
adev->have_atomics_support = false;
/* APUs w/ gfx9 onwards don't rely on PCIe atomics: the internal path
* natively supports atomics, so enable it (mirrors the __linux__ case).
* Without this the userspace gfx submission path stalls the gfx ring.
*/
if ((adev->flags & AMD_IS_APU) &&
(amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(9, 0, 0)))
adev->have_atomics_support = true;
else
adev->have_atomics_support = false;
#endif

if (!adev->have_atomics_support)
Expand Down
35 changes: 35 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -4109,6 +4109,16 @@ static void gfx_v10_0_check_gfxoff_flag(struct amdgpu_device *adev)
if (!gfx_v10_0_navi10_gfxoff_should_enable(adev))
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
break;
#ifdef __FreeBSD__
case IP_VERSION(10, 3, 6):
/* Raphael APU: GFXOFF wake via SMU is broken under LinuxKPI,
* leaving the gfx ring stuck (ring gfx_0.0.0 timeout) followed
* by a GPU reset loop. Disable GFXOFF until the SMU handshake
* works on FreeBSD.
*/
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
break;
#endif
default:
break;
}
Expand Down Expand Up @@ -7163,6 +7173,31 @@ static int gfx_v10_0_cp_resume(struct amdgpu_device *adev)
return r;
}

#ifdef __FreeBSD__
/*
* On this APU under LinuxKPI the doorbell does not wake the CP/MEC
* once a queue has gone idle, so GPU-scheduler submissions issued
* after the boot-time idle-poll window are never fetched (ring
* gfx_0.0.0 timeout, signaled seq < emitted seq, with no VM fault).
* Keep the engines polling the queue write pointer from memory rather
* than relying on a doorbell wake: aim the GFX-pipe wptr poll at the
* ring's wptr writeback, max out the idle poll count, and enable MEC
* wptr polling (per-queue poll address comes from each MQD).
*/
if (adev->gfx.num_gfx_rings) {
uint64_t wptr_gpu_addr = adev->gfx.gfx_ring[0].wptr_gpu_addr;

WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_ADDR_LO,
lower_32_bits(wptr_gpu_addr));
WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_ADDR_HI,
upper_32_bits(wptr_gpu_addr));
}
WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_CNTL,
(0x0100 << CP_RB_WPTR_POLL_CNTL__POLL_FREQUENCY__SHIFT) |
(0xffff << CP_RB_WPTR_POLL_CNTL__IDLE_POLL_COUNT__SHIFT));
WREG32_FIELD15(GC, 0, CP_PQ_WPTR_POLL_CNTL, EN, 1);
#endif

return 0;
}

Expand Down