aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c48
2 files changed, 46 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index d02f248b2028..0fa6438c152c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1209,6 +1209,7 @@ struct amdgpu_sdma_instance {
struct amdgpu_ring ring;
bool burst_nop;
+ uint32_t poll_mem_offs;
};
struct amdgpu_sdma {
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 591f3e7fb508..5c247082f699 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -35,6 +35,7 @@
#include "vega10/MMHUB/mmhub_1_0_offset.h"
#include "vega10/MMHUB/mmhub_1_0_sh_mask.h"
#include "vega10/HDP/hdp_4_0_offset.h"
+#include "vega10/NBIO/nbio_6_1_offset.h"
#include "raven1/SDMA0/sdma0_4_1_default.h"
#include "soc15_common.h"
@@ -287,6 +288,8 @@ static uint64_t sdma_v4_0_ring_get_wptr(struct amdgpu_ring *ring)
*/
static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
{
+ int i;
+ u32 offset;
struct amdgpu_device *adev = ring->adev;
DRM_DEBUG("Setting write pointer\n");
@@ -303,6 +306,17 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
adev->wb.wb[ring->wptr_offs + 1] = upper_32_bits(ring->wptr << 2);
DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
ring->doorbell_index, ring->wptr << 2);
+
+ if (amdgpu_sriov_vf(adev)) {
+ for (i = 0; i < adev->sdma.num_instances; i++) {
+ if (&adev->sdma.instance[i].ring == ring) {
+ offset = adev->sdma.instance[i].poll_mem_offs;
+ atomic64_set((atomic64_t *)&adev->wb.wb[offset],
+ (ring->wptr << 2));
+ nbio_v6_1_hdp_flush(adev);
+ }
+ }
+ }
WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
} else {
int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1;
@@ -573,9 +587,9 @@ static void sdma_v4_0_enable(struct amdgpu_device *adev, bool enable)
static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
{
struct amdgpu_ring *ring;
- u32 rb_cntl, ib_cntl;
+ u32 rb_cntl, ib_cntl, wptr_poll_addr_lo, wptr_poll_addr_hi, wptr_poll_cntl;
u32 rb_bufsz;
- u32 wb_offset;
+ u32 wb_offset, poll_offset;
u32 doorbell;
u32 doorbell_offset;
u32 temp;
@@ -687,6 +701,21 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev)
if (adev->mman.buffer_funcs_ring == ring)
amdgpu_ttm_set_active_vram_size(adev, adev->mc.real_vram_size);
+
+ if (amdgpu_sriov_vf(adev)) {
+ poll_offset = adev->sdma.instance[i].poll_mem_offs * 4;
+
+ wptr_poll_cntl = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL));
+ wptr_poll_addr_lo = RREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO));
+ wptr_poll_addr_lo = REG_SET_FIELD(wptr_poll_addr_lo, SDMA0_GFX_RB_WPTR_POLL_ADDR_LO, ADDR,
+ lower_32_bits(adev->wb.gpu_addr + poll_offset) >> 2);
+ wptr_poll_addr_hi = upper_32_bits(adev->wb.gpu_addr + poll_offset);
+ wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 1);
+
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_LO), wptr_poll_addr_lo);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI), wptr_poll_addr_hi);
+ WREG32(sdma_v4_0_get_reg_offset(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL), wptr_poll_cntl);
+ }
}
return 0;
@@ -1247,6 +1276,15 @@ static int sdma_v4_0_sw_init(void *handle)
(i == 0) ?
AMDGPU_SDMA_IRQ_TRAP0 :
AMDGPU_SDMA_IRQ_TRAP1);
+
+ if (amdgpu_sriov_vf(adev)) {
+ r = amdgpu_wb_get_64bit(adev,
+ &adev->sdma.instance[i].poll_mem_offs);
+ if (r) {
+ dev_err(adev->dev, "(%d) failed to allocate SDMA poll mem wb.\n", r);
+ return r;
+ }
+ }
if (r)
return r;
}
@@ -1259,9 +1297,13 @@ static int sdma_v4_0_sw_fini(void *handle)
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
int i;
- for (i = 0; i < adev->sdma.num_instances; i++)
+ for (i = 0; i < adev->sdma.num_instances; i++) {
amdgpu_ring_fini(&adev->sdma.instance[i].ring);
+ if (amdgpu_sriov_vf(adev))
+ amdgpu_wb_free_64bit(adev,
+ adev->sdma.instance[i].poll_mem_offs);
+ }
return 0;
}