Skip to content

Commit 355d743

Browse files
veerabadhrangregkh
authored andcommitted
drm/amdgpu: vcn and jpeg ring synchronization
commit 187561d upstream. Synchronize the ring usage for vcn1 and jpeg1 to workaround a hardware bug. Signed-off-by: Veerabadhran Gopalakrishnan <veerabadhran.gopalakrishnan@amd.com> Acked-by: Christian König <christian.koenig@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent f77758e commit 355d743

5 files changed

Lines changed: 51 additions & 7 deletions

File tree

drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
6868

6969
INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
7070
mutex_init(&adev->vcn.vcn_pg_lock);
71+
mutex_init(&adev->vcn.vcn1_jpeg1_workaround);
7172
atomic_set(&adev->vcn.total_submission_cnt, 0);
7273
for (i = 0; i < adev->vcn.num_vcn_inst; i++)
7374
atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0);
@@ -237,6 +238,7 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
237238
}
238239

239240
release_firmware(adev->vcn.fw);
241+
mutex_destroy(&adev->vcn.vcn1_jpeg1_workaround);
240242
mutex_destroy(&adev->vcn.vcn_pg_lock);
241243

242244
return 0;

drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ struct amdgpu_vcn {
220220
struct amdgpu_vcn_inst inst[AMDGPU_MAX_VCN_INSTANCES];
221221
struct amdgpu_vcn_reg internal;
222222
struct mutex vcn_pg_lock;
223+
struct mutex vcn1_jpeg1_workaround;
223224
atomic_t total_submission_cnt;
224225

225226
unsigned harvest_config;

drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
3535
static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev);
36+
static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring);
3637

3738
static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val)
3839
{
@@ -564,8 +565,8 @@ static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = {
564565
.insert_start = jpeg_v1_0_decode_ring_insert_start,
565566
.insert_end = jpeg_v1_0_decode_ring_insert_end,
566567
.pad_ib = amdgpu_ring_generic_pad_ib,
567-
.begin_use = vcn_v1_0_ring_begin_use,
568-
.end_use = amdgpu_vcn_ring_end_use,
568+
.begin_use = jpeg_v1_0_ring_begin_use,
569+
.end_use = vcn_v1_0_ring_end_use,
569570
.emit_wreg = jpeg_v1_0_decode_ring_emit_wreg,
570571
.emit_reg_wait = jpeg_v1_0_decode_ring_emit_reg_wait,
571572
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
@@ -586,3 +587,22 @@ static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev)
586587
{
587588
adev->jpeg.inst->irq.funcs = &jpeg_v1_0_irq_funcs;
588589
}
590+
591+
static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring)
592+
{
593+
struct amdgpu_device *adev = ring->adev;
594+
bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
595+
int cnt = 0;
596+
597+
mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);
598+
599+
if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_dec))
600+
DRM_ERROR("JPEG dec: vcn dec ring may not be empty\n");
601+
602+
for (cnt = 0; cnt < adev->vcn.num_enc_rings; cnt++) {
603+
if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_enc[cnt]))
604+
DRM_ERROR("JPEG dec: vcn enc ring[%d] may not be empty\n", cnt);
605+
}
606+
607+
vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
608+
}

drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
5454
int inst_idx, struct dpg_pause_state *new_state);
5555

5656
static void vcn_v1_0_idle_work_handler(struct work_struct *work);
57+
static void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring);
5758

5859
/**
5960
* vcn_v1_0_early_init - set function pointers
@@ -1804,11 +1805,24 @@ static void vcn_v1_0_idle_work_handler(struct work_struct *work)
18041805
}
18051806
}
18061807

1807-
void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring)
1808+
static void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring)
18081809
{
1809-
struct amdgpu_device *adev = ring->adev;
1810+
struct amdgpu_device *adev = ring->adev;
18101811
bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
18111812

1813+
mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);
1814+
1815+
if (amdgpu_fence_wait_empty(&ring->adev->jpeg.inst->ring_dec))
1816+
DRM_ERROR("VCN dec: jpeg dec ring may not be empty\n");
1817+
1818+
vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
1819+
1820+
}
1821+
1822+
void vcn_v1_0_set_pg_for_begin_use(struct amdgpu_ring *ring, bool set_clocks)
1823+
{
1824+
struct amdgpu_device *adev = ring->adev;
1825+
18121826
if (set_clocks) {
18131827
amdgpu_gfx_off_ctrl(adev, false);
18141828
if (adev->pm.dpm_enabled)
@@ -1844,6 +1858,12 @@ void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring)
18441858
}
18451859
}
18461860

1861+
void vcn_v1_0_ring_end_use(struct amdgpu_ring *ring)
1862+
{
1863+
schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
1864+
mutex_unlock(&ring->adev->vcn.vcn1_jpeg1_workaround);
1865+
}
1866+
18471867
static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
18481868
.name = "vcn_v1_0",
18491869
.early_init = vcn_v1_0_early_init,
@@ -1891,7 +1911,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {
18911911
.insert_end = vcn_v1_0_dec_ring_insert_end,
18921912
.pad_ib = amdgpu_ring_generic_pad_ib,
18931913
.begin_use = vcn_v1_0_ring_begin_use,
1894-
.end_use = amdgpu_vcn_ring_end_use,
1914+
.end_use = vcn_v1_0_ring_end_use,
18951915
.emit_wreg = vcn_v1_0_dec_ring_emit_wreg,
18961916
.emit_reg_wait = vcn_v1_0_dec_ring_emit_reg_wait,
18971917
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
@@ -1923,7 +1943,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = {
19231943
.insert_end = vcn_v1_0_enc_ring_insert_end,
19241944
.pad_ib = amdgpu_ring_generic_pad_ib,
19251945
.begin_use = vcn_v1_0_ring_begin_use,
1926-
.end_use = amdgpu_vcn_ring_end_use,
1946+
.end_use = vcn_v1_0_ring_end_use,
19271947
.emit_wreg = vcn_v1_0_enc_ring_emit_wreg,
19281948
.emit_reg_wait = vcn_v1_0_enc_ring_emit_reg_wait,
19291949
.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,

drivers/gpu/drm/amd/amdgpu/vcn_v1_0.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
#ifndef __VCN_V1_0_H__
2525
#define __VCN_V1_0_H__
2626

27-
void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring);
27+
void vcn_v1_0_ring_end_use(struct amdgpu_ring *ring);
28+
void vcn_v1_0_set_pg_for_begin_use(struct amdgpu_ring *ring, bool set_clocks);
2829

2930
extern const struct amdgpu_ip_block_version vcn_v1_0_ip_block;
3031

0 commit comments

Comments
 (0)