Skip to content

Commit 2f0268c

Browse files
fanhuangalexdeucher
authored andcommitted
drm/amdgpu/jpeg: sriov support for jpeg_v5_0_1
initialization table handshake with mmsch Signed-off-by: fanhuang <[email protected]> Acked-by: Alex Deucher <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 56fc141 commit 2f0268c

File tree

1 file changed

+131
-11
lines changed

1 file changed

+131
-11
lines changed

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

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@
2828
#include "soc15d.h"
2929
#include "jpeg_v4_0_3.h"
3030
#include "jpeg_v5_0_1.h"
31+
#include "mmsch_v5_0.h"
3132

3233
#include "vcn/vcn_5_0_0_offset.h"
3334
#include "vcn/vcn_5_0_0_sh_mask.h"
3435
#include "ivsrcid/vcn/irqsrcs_vcn_5_0.h"
3536

37+
static int jpeg_v5_0_1_start_sriov(struct amdgpu_device *adev);
3638
static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev);
3739
static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev);
3840
static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
@@ -163,14 +165,9 @@ static int jpeg_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block)
163165
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
164166
1 + j + 11 * jpeg_inst;
165167
} else {
166-
if (j < 4)
167-
ring->doorbell_index =
168-
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
169-
4 + j + 32 * jpeg_inst;
170-
else
171-
ring->doorbell_index =
172-
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
173-
8 + j + 32 * jpeg_inst;
168+
ring->doorbell_index =
169+
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
170+
2 + j + 32 * jpeg_inst;
174171
}
175172
sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j);
176173
r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
@@ -237,7 +234,10 @@ static int jpeg_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block)
237234
int i, j, r, jpeg_inst;
238235

239236
if (amdgpu_sriov_vf(adev)) {
240-
/* jpeg_v5_0_1_start_sriov(adev); */
237+
r = jpeg_v5_0_1_start_sriov(adev);
238+
if (r)
239+
return r;
240+
241241
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
242242
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
243243
ring = &adev->jpeg.inst[i].ring_dec[j];
@@ -291,8 +291,10 @@ static int jpeg_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block)
291291

292292
cancel_delayed_work_sync(&adev->jpeg.idle_work);
293293

294-
if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
295-
ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
294+
if (!amdgpu_sriov_vf(adev)) {
295+
if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
296+
ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
297+
}
296298

297299
return ret;
298300
}
@@ -422,6 +424,119 @@ static void jpeg_v5_0_1_init_jrbc(struct amdgpu_ring *ring)
422424
reg_offset);
423425
}
424426

427+
static int jpeg_v5_0_1_start_sriov(struct amdgpu_device *adev)
428+
{
429+
struct amdgpu_ring *ring;
430+
uint64_t ctx_addr;
431+
uint32_t param, resp, expected;
432+
uint32_t tmp, timeout;
433+
434+
struct amdgpu_mm_table *table = &adev->virt.mm_table;
435+
uint32_t *table_loc;
436+
uint32_t table_size;
437+
uint32_t size, size_dw, item_offset;
438+
uint32_t init_status;
439+
int i, j, jpeg_inst;
440+
441+
struct mmsch_v5_0_cmd_direct_write
442+
direct_wt = { {0} };
443+
struct mmsch_v5_0_cmd_end end = { {0} };
444+
struct mmsch_v5_0_init_header header;
445+
446+
direct_wt.cmd_header.command_type =
447+
MMSCH_COMMAND__DIRECT_REG_WRITE;
448+
end.cmd_header.command_type =
449+
MMSCH_COMMAND__END;
450+
451+
for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
452+
jpeg_inst = GET_INST(JPEG, i);
453+
454+
memset(&header, 0, sizeof(struct mmsch_v5_0_init_header));
455+
header.version = MMSCH_VERSION;
456+
header.total_size = sizeof(struct mmsch_v5_0_init_header) >> 2;
457+
458+
table_loc = (uint32_t *)table->cpu_addr;
459+
table_loc += header.total_size;
460+
461+
item_offset = header.total_size;
462+
463+
for (j = 0; j < adev->jpeg.num_jpeg_rings; j++) {
464+
ring = &adev->jpeg.inst[i].ring_dec[j];
465+
table_size = 0;
466+
467+
tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW);
468+
MMSCH_V5_0_INSERT_DIRECT_WT(tmp, lower_32_bits(ring->gpu_addr));
469+
tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH);
470+
MMSCH_V5_0_INSERT_DIRECT_WT(tmp, upper_32_bits(ring->gpu_addr));
471+
tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JRBC_RB_SIZE);
472+
MMSCH_V5_0_INSERT_DIRECT_WT(tmp, ring->ring_size / 4);
473+
474+
if (j < 5) {
475+
header.mjpegdec0[j].table_offset = item_offset;
476+
header.mjpegdec0[j].init_status = 0;
477+
header.mjpegdec0[j].table_size = table_size;
478+
} else {
479+
header.mjpegdec1[j - 5].table_offset = item_offset;
480+
header.mjpegdec1[j - 5].init_status = 0;
481+
header.mjpegdec1[j - 5].table_size = table_size;
482+
}
483+
header.total_size += table_size;
484+
item_offset += table_size;
485+
}
486+
487+
MMSCH_V5_0_INSERT_END();
488+
489+
/* send init table to MMSCH */
490+
size = sizeof(struct mmsch_v5_0_init_header);
491+
table_loc = (uint32_t *)table->cpu_addr;
492+
memcpy((void *)table_loc, &header, size);
493+
494+
ctx_addr = table->gpu_addr;
495+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
496+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
497+
498+
tmp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID);
499+
tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
500+
tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
501+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID, tmp);
502+
503+
size = header.total_size;
504+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_SIZE, size);
505+
506+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP, 0);
507+
508+
param = 0x00000001;
509+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_HOST, param);
510+
tmp = 0;
511+
timeout = 1000;
512+
resp = 0;
513+
expected = MMSCH_VF_MAILBOX_RESP__OK;
514+
init_status =
515+
((struct mmsch_v5_0_init_header *)(table_loc))->mjpegdec0[i].init_status;
516+
while (resp != expected) {
517+
resp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP);
518+
519+
if (resp != 0)
520+
break;
521+
udelay(10);
522+
tmp = tmp + 10;
523+
if (tmp >= timeout) {
524+
DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
525+
" waiting for regMMSCH_VF_MAILBOX_RESP "\
526+
"(expected=0x%08x, readback=0x%08x)\n",
527+
tmp, expected, resp);
528+
return -EBUSY;
529+
}
530+
}
531+
if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE &&
532+
init_status != MMSCH_VF_ENGINE_STATUS__PASS)
533+
DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init status for jpeg: %x\n",
534+
resp, init_status);
535+
536+
}
537+
return 0;
538+
}
539+
425540
/**
426541
* jpeg_v5_0_1_start - start JPEG block
427542
*
@@ -581,6 +696,11 @@ static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
581696
struct amdgpu_device *adev = ip_block->adev;
582697
int ret;
583698

699+
if (amdgpu_sriov_vf(adev)) {
700+
adev->jpeg.cur_state = AMD_PG_STATE_UNGATE;
701+
return 0;
702+
}
703+
584704
if (state == adev->jpeg.cur_state)
585705
return 0;
586706

0 commit comments

Comments
 (0)