diff options
| author | Dave Airlie <airlied@redhat.com> | 2026-01-15 14:49:33 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2026-01-15 14:49:33 +1000 |
| commit | 83dc0ba2755296b5e5882e044c80973b7c3fce9e (patch) | |
| tree | 53774323449c41eb1b17e101be83197c6b5cbb82 /drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | |
| parent | a87fef0880c4f52769b5a3c2fc1b2d73aaa04eb3 (diff) | |
| parent | 38a0f4cf8c6147fd10baa206ab349f8ff724e391 (diff) | |
Merge tag 'amd-drm-next-6.20-2026-01-09' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-6.20-2026-01-09:
amdgpu:
- GPUVM updates
- Initial support for larger GPU address spaces
- Initial SMUIO 15.x support
- Documentation updates
- Initial PSP 15.x support
- Initial IH 7.1 support
- Initial IH 6.1.1 support
- SMU 13.0.12 updates
- RAS updates
- Initial MMHUB 3.4 support
- Initial MMHUB 4.2 support
- Initial GC 12.1 support
- Initial GC 11.5.4 support
- HDMI fixes
- Panel replay improvements
- DML updates
- DC FP fixes
- Initial SDMA 6.1.4 support
- Initial SDMA 7.1 support
- Userq updates
- DC HPD refactor
- SwSMU cleanups and refactoring
- TTM memory ops parallelization
- DCN 3.5 fixes
- DP audio fixes
- Clang fixes
- Misc spelling fixes and cleanups
- Initial SDMA 7.11.4 support
- Convert legacy DRM logging helpers to new drm logging helpers
- Initial JPEG 5.3 support
- Add support for changing UMA size via the driver
- DC analog fixes
- GC 9 gfx queue reset support
- Initial SMU 15.x support
amdkfd:
- Reserved SDMA rework
- Refactor SPM
- Initial GC 12.1 support
- Initial GC 11.5.4 support
- Initial SDMA 7.1 support
- Initial SDMA 6.1.4 support
- Increase the kfd process hash table
- Per context support
- Topology fixes
radeon:
- Convert legacy DRM logging helpers to new drm logging helpers
- Use devm for i2c adapters
- Variable sized array fix
- Misc cleanups
UAPI:
- KFD context support. Proposed userspace:
https://github.com/ROCm/rocm-systems/pull/1705
https://github.com/ROCm/rocm-systems/pull/1701
- Add userq metadata queries for more queue types. Proposed userspace:
https://gitlab.freedesktop.org/yogeshmohan/mesa/-/commits/userq_query
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260109154713.3242957-1-alexander.deucher@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 47a6ce4fdc74..f8eac92a2b36 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -37,6 +37,7 @@ #include "vi.h" #include "soc15.h" #include "nv.h" +#include "amdgpu_virt_ras_cmd.h" #define POPULATE_UCODE_INFO(vf2pf_info, ucode, ver) \ do { \ @@ -1337,6 +1338,133 @@ bool amdgpu_virt_get_rlcg_reg_access_flag(struct amdgpu_device *adev, return ret; } +static u32 amdgpu_virt_rlcg_vfi_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id) +{ + uint32_t timeout = 100; + uint32_t i; + + struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl; + void *vfi_cmd; + void *vfi_stat; + void *vfi_addr; + void *vfi_data; + void *vfi_grbm_cntl; + void *vfi_grbm_idx; + uint32_t cmd; + uint32_t stat; + uint32_t addr = offset; + uint32_t data; + uint32_t grbm_cntl_data; + uint32_t grbm_idx_data; + + unsigned long flags; + bool is_err = true; + + if (!adev->gfx.rlc.rlcg_reg_access_supported) { + dev_err(adev->dev, "VFi interface is not available\n"); + return 0; + } + + if (adev->gfx.xcc_mask && (((1 << xcc_id) & adev->gfx.xcc_mask) == 0)) { + dev_err(adev->dev, "VFi invalid XCC, xcc_id=0x%x\n", xcc_id); + return 0; + } + + if (amdgpu_device_skip_hw_access(adev)) + return 0; + + reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[xcc_id]; + vfi_cmd = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_cmd; + vfi_stat = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_stat; + vfi_addr = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_addr; + vfi_data = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_data; + vfi_grbm_cntl = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_grbm_cntl; + vfi_grbm_idx = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->vfi_grbm_idx; + grbm_cntl_data = reg_access_ctrl->vfi_grbm_cntl_data; + grbm_idx_data = reg_access_ctrl->vfi_grbm_idx_data; + + if (flag == AMDGPU_RLCG_GC_WRITE) { + data = v; + cmd = AMDGPU_RLCG_VFI_CMD__WR; + + // the GRBM_GFX_CNTL and GRBM_GFX_INDEX are protected by mutex outside this call + if (addr == reg_access_ctrl->grbm_cntl) { + reg_access_ctrl->vfi_grbm_cntl_data = data; + return 0; + } else if (addr == reg_access_ctrl->grbm_idx) { + reg_access_ctrl->vfi_grbm_idx_data = data; + return 0; + } + + } else if (flag == AMDGPU_RLCG_GC_READ) { + data = 0; + cmd = AMDGPU_RLCG_VFI_CMD__RD; + + // the GRBM_GFX_CNTL and GRBM_GFX_INDEX are protected by mutex outside this call + if (addr == reg_access_ctrl->grbm_cntl) + return grbm_cntl_data; + else if (addr == reg_access_ctrl->grbm_idx) + return grbm_idx_data; + + } else { + dev_err(adev->dev, "VFi invalid access, flag=0x%x\n", flag); + return 0; + } + + spin_lock_irqsave(&adev->virt.rlcg_reg_lock, flags); + + writel(addr, vfi_addr); + writel(data, vfi_data); + writel(grbm_cntl_data, vfi_grbm_cntl); + writel(grbm_idx_data, vfi_grbm_idx); + + writel(AMDGPU_RLCG_VFI_STAT__BUSY, vfi_stat); + writel(cmd, vfi_cmd); + + for (i = 0; i < timeout; i++) { + stat = readl(vfi_stat); + if (stat != AMDGPU_RLCG_VFI_STAT__BUSY) + break; + udelay(10); + } + + switch (stat) { + case AMDGPU_RLCG_VFI_STAT__DONE: + is_err = false; + if (cmd == AMDGPU_RLCG_VFI_CMD__RD) + data = readl(vfi_data); + break; + case AMDGPU_RLCG_VFI_STAT__BUSY: + dev_err(adev->dev, "VFi access timeout\n"); + break; + case AMDGPU_RLCG_VFI_STAT__INV_CMD: + dev_err(adev->dev, "VFi invalid command\n"); + break; + case AMDGPU_RLCG_VFI_STAT__INV_ADDR: + dev_err(adev->dev, "VFi invalid address\n"); + break; + case AMDGPU_RLCG_VFI_STAT__ERR: + dev_err(adev->dev, "VFi unknown error\n"); + break; + default: + dev_err(adev->dev, "VFi unknown status code\n"); + break; + } + + spin_unlock_irqrestore(&adev->virt.rlcg_reg_lock, flags); + + if (is_err) + dev_err(adev->dev, "VFi: [grbm_cntl=0x%x grbm_idx=0x%x] addr=0x%x (byte addr 0x%x), data=0x%x, cmd=0x%x\n", + grbm_cntl_data, grbm_idx_data, + addr, addr * 4, data, cmd); + else + dev_dbg(adev->dev, "VFi: [grbm_cntl=0x%x grbm_idx=0x%x] addr=0x%x (byte addr 0x%x), data=0x%x, cmd=0x%x\n", + grbm_cntl_data, grbm_idx_data, + addr, addr * 4, data, cmd); + + return data; +} + u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 flag, u32 xcc_id) { struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl; @@ -1350,6 +1478,9 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v, u32 f void *spare_int; unsigned long flags; + if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 1, 0)) + return amdgpu_virt_rlcg_vfi_reg_rw(adev, offset, v, flag, xcc_id); + if (!adev->gfx.rlc.rlcg_reg_access_supported) { dev_err(adev->dev, "indirect registers access through rlcg is not available\n"); @@ -1533,6 +1664,9 @@ bool amdgpu_virt_get_ras_capability(struct amdgpu_device *adev) if (adev->virt.ras_en_caps.bits.poison_propogation_mode) con->poison_supported = true; /* Poison is handled by host */ + if (adev->virt.ras_en_caps.bits.uniras_supported) + amdgpu_virt_ras_set_remote_uniras(adev, true); + return true; } @@ -1845,3 +1979,28 @@ int amdgpu_virt_check_vf_critical_region(struct amdgpu_device *adev, u64 addr, b return r; } + +static int req_remote_ras_cmd(struct amdgpu_device *adev, + u32 param1, u32 param2, u32 param3) +{ + struct amdgpu_virt *virt = &adev->virt; + + if (virt->ops && virt->ops->req_remote_ras_cmd) + return virt->ops->req_remote_ras_cmd(adev, param1, param2, param3); + return -ENOENT; +} + +int amdgpu_virt_send_remote_ras_cmd(struct amdgpu_device *adev, + uint64_t buf, uint32_t buf_len) +{ + uint64_t gpa = buf; + int ret = -EIO; + + if (down_read_trylock(&adev->reset_domain->sem)) { + ret = req_remote_ras_cmd(adev, + lower_32_bits(gpa), upper_32_bits(gpa), buf_len); + up_read(&adev->reset_domain->sem); + } + + return ret; +} |
