Skip to content

Commit

Permalink
drm/amdgpu/sriov: Use kiq to copy the gpu clock
Browse files Browse the repository at this point in the history
For vega10 sriov, the register is blocked, use
copy data command to fix the issue.

v2: Rename amdgpu_kiq_read_clock to gfx_v9_0_kiq_read_clock.

Signed-off-by: Emily Deng <Emily.Deng@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
EmilyDeng666 authored and alexdeucher committed Feb 28, 2020
1 parent f2cc50c commit 89510a2
Showing 1 changed file with 58 additions and 10 deletions.
68 changes: 58 additions & 10 deletions drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -3963,23 +3963,71 @@ static int gfx_v9_0_soft_reset(void *handle)
return 0;
}

static uint64_t gfx_v9_0_kiq_read_clock(struct amdgpu_device *adev)
{
signed long r, cnt = 0;
unsigned long flags;
uint32_t seq;
struct amdgpu_kiq *kiq = &adev->gfx.kiq;
struct amdgpu_ring *ring = &kiq->ring;

BUG_ON(!ring->funcs->emit_rreg);

spin_lock_irqsave(&kiq->ring_lock, flags);
amdgpu_ring_alloc(ring, 32);
amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));
amdgpu_ring_write(ring, 9 | /* src: register*/
(5 << 8) | /* dst: memory */
(1 << 16) | /* count sel */
(1 << 20)); /* write confirm */
amdgpu_ring_write(ring, 0);
amdgpu_ring_write(ring, 0);
amdgpu_ring_write(ring, lower_32_bits(adev->wb.gpu_addr +
kiq->reg_val_offs * 4));
amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
kiq->reg_val_offs * 4));
amdgpu_fence_emit_polling(ring, &seq);
amdgpu_ring_commit(ring);
spin_unlock_irqrestore(&kiq->ring_lock, flags);

r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);

/* don't wait anymore for gpu reset case because this way may
* block gpu_recover() routine forever, e.g. this virt_kiq_rreg
* is triggered in TTM and ttm_bo_lock_delayed_workqueue() will
* never return if we keep waiting in virt_kiq_rreg, which cause
* gpu_recover() hang there.
*
* also don't wait anymore for IRQ context
* */
if (r < 1 && (adev->in_gpu_reset || in_interrupt()))
goto failed_kiq_read;

might_sleep();
while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
}

if (cnt > MAX_KIQ_REG_TRY)
goto failed_kiq_read;

return (uint64_t)adev->wb.wb[kiq->reg_val_offs] |
(uint64_t)adev->wb.wb[kiq->reg_val_offs + 1 ] << 32ULL;

failed_kiq_read:
pr_err("failed to read gpu clock\n");
return ~0;
}

static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev)
{
uint64_t clock;

amdgpu_gfx_off_ctrl(adev, false);
mutex_lock(&adev->gfx.gpu_clock_mutex);
if (adev->asic_type == CHIP_VEGA10 && amdgpu_sriov_runtime(adev)) {
uint32_t tmp, lsb, msb, i = 0;
do {
if (i != 0)
udelay(1);
tmp = RREG32_SOC15(GC, 0, mmRLC_REFCLOCK_TIMESTAMP_MSB);
lsb = RREG32_SOC15(GC, 0, mmRLC_REFCLOCK_TIMESTAMP_LSB);
msb = RREG32_SOC15(GC, 0, mmRLC_REFCLOCK_TIMESTAMP_MSB);
i++;
} while (unlikely(tmp != msb) && (i < adev->usec_timeout));
clock = (uint64_t)lsb | ((uint64_t)msb << 32ULL);
clock = gfx_v9_0_kiq_read_clock(adev);
} else {
WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1);
clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) |
Expand Down

0 comments on commit 89510a2

Please sign in to comment.