Skip to content

Commit d34fecc

Browse files
Samir Dhumealexdeucher
authored andcommitted
drm/amdgpu/jpeg: sriov support for jpeg_v4_0_3
initialization table handshake with mmsch Signed-off-by: Samir Dhume <samir.dhume@amd.com> Acked-by: Leo Liu <leo.liu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent 81a7be7 commit d34fecc

File tree

1 file changed

+151
-20
lines changed

1 file changed

+151
-20
lines changed

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

Lines changed: 151 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "soc15.h"
2727
#include "soc15d.h"
2828
#include "jpeg_v4_0_3.h"
29+
#include "mmsch_v4_0_3.h"
2930

3031
#include "vcn/vcn_4_0_3_offset.h"
3132
#include "vcn/vcn_4_0_3_sh_mask.h"
@@ -41,6 +42,7 @@ static void jpeg_v4_0_3_set_irq_funcs(struct amdgpu_device *adev);
4142
static int jpeg_v4_0_3_set_powergating_state(void *handle,
4243
enum amd_powergating_state state);
4344
static void jpeg_v4_0_3_set_ras_funcs(struct amdgpu_device *adev);
45+
static void jpeg_v4_0_3_dec_ring_set_wptr(struct amdgpu_ring *ring);
4446

4547
static int amdgpu_ih_srcid_jpeg[] = {
4648
VCN_4_0__SRCID__JPEG_DECODE,
@@ -171,6 +173,119 @@ static int jpeg_v4_0_3_sw_fini(void *handle)
171173
return r;
172174
}
173175

176+
static int jpeg_v4_0_3_start_sriov(struct amdgpu_device *adev)
177+
{
178+
struct amdgpu_ring *ring;
179+
uint64_t ctx_addr;
180+
uint32_t param, resp, expected;
181+
uint32_t tmp, timeout;
182+
183+
struct amdgpu_mm_table *table = &adev->virt.mm_table;
184+
uint32_t *table_loc;
185+
uint32_t table_size;
186+
uint32_t size, size_dw, item_offset;
187+
uint32_t init_status;
188+
int i, j, jpeg_inst;
189+
190+
struct mmsch_v4_0_cmd_direct_write
191+
direct_wt = { {0} };
192+
struct mmsch_v4_0_cmd_end end = { {0} };
193+
struct mmsch_v4_0_3_init_header header;
194+
195+
direct_wt.cmd_header.command_type =
196+
MMSCH_COMMAND__DIRECT_REG_WRITE;
197+
end.cmd_header.command_type =
198+
MMSCH_COMMAND__END;
199+
200+
for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
201+
jpeg_inst = GET_INST(JPEG, i);
202+
203+
memset(&header, 0, sizeof(struct mmsch_v4_0_3_init_header));
204+
header.version = MMSCH_VERSION;
205+
header.total_size = sizeof(struct mmsch_v4_0_3_init_header) >> 2;
206+
207+
table_loc = (uint32_t *)table->cpu_addr;
208+
table_loc += header.total_size;
209+
210+
item_offset = header.total_size;
211+
212+
for (j = 0; j < adev->jpeg.num_jpeg_rings; j++) {
213+
ring = &adev->jpeg.inst[i].ring_dec[j];
214+
table_size = 0;
215+
216+
tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_LOW);
217+
MMSCH_V4_0_INSERT_DIRECT_WT(tmp, lower_32_bits(ring->gpu_addr));
218+
tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI0_UVD_LMI_JRBC_RB_64BIT_BAR_HIGH);
219+
MMSCH_V4_0_INSERT_DIRECT_WT(tmp, upper_32_bits(ring->gpu_addr));
220+
tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_SIZE);
221+
MMSCH_V4_0_INSERT_DIRECT_WT(tmp, ring->ring_size / 4);
222+
223+
if (j <= 3) {
224+
header.mjpegdec0[j].table_offset = item_offset;
225+
header.mjpegdec0[j].init_status = 0;
226+
header.mjpegdec0[j].table_size = table_size;
227+
} else {
228+
header.mjpegdec1[j - 4].table_offset = item_offset;
229+
header.mjpegdec1[j - 4].init_status = 0;
230+
header.mjpegdec1[j - 4].table_size = table_size;
231+
}
232+
header.total_size += table_size;
233+
item_offset += table_size;
234+
}
235+
236+
MMSCH_V4_0_INSERT_END();
237+
238+
/* send init table to MMSCH */
239+
size = sizeof(struct mmsch_v4_0_3_init_header);
240+
table_loc = (uint32_t *)table->cpu_addr;
241+
memcpy((void *)table_loc, &header, size);
242+
243+
ctx_addr = table->gpu_addr;
244+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
245+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
246+
247+
tmp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID);
248+
tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
249+
tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
250+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID, tmp);
251+
252+
size = header.total_size;
253+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_SIZE, size);
254+
255+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP, 0);
256+
257+
param = 0x00000001;
258+
WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_HOST, param);
259+
tmp = 0;
260+
timeout = 1000;
261+
resp = 0;
262+
expected = MMSCH_VF_MAILBOX_RESP__OK;
263+
init_status =
264+
((struct mmsch_v4_0_3_init_header *)(table_loc))->mjpegdec0[i].init_status;
265+
while (resp != expected) {
266+
resp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP);
267+
268+
if (resp != 0)
269+
break;
270+
udelay(10);
271+
tmp = tmp + 10;
272+
if (tmp >= timeout) {
273+
DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
274+
" waiting for regMMSCH_VF_MAILBOX_RESP "\
275+
"(expected=0x%08x, readback=0x%08x)\n",
276+
tmp, expected, resp);
277+
return -EBUSY;
278+
}
279+
}
280+
if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE &&
281+
init_status != MMSCH_VF_ENGINE_STATUS__PASS)
282+
DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init status for jpeg: %x\n",
283+
resp, init_status);
284+
285+
}
286+
return 0;
287+
}
288+
174289
/**
175290
* jpeg_v4_0_3_hw_init - start and test JPEG block
176291
*
@@ -183,31 +298,47 @@ static int jpeg_v4_0_3_hw_init(void *handle)
183298
struct amdgpu_ring *ring;
184299
int i, j, r, jpeg_inst;
185300

186-
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
187-
jpeg_inst = GET_INST(JPEG, i);
301+
if (amdgpu_sriov_vf(adev)) {
302+
r = jpeg_v4_0_3_start_sriov(adev);
303+
if (r)
304+
return r;
188305

189-
ring = adev->jpeg.inst[i].ring_dec;
306+
for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
307+
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
308+
ring = &adev->jpeg.inst[i].ring_dec[j];
309+
ring->wptr = 0;
310+
ring->wptr_old = 0;
311+
jpeg_v4_0_3_dec_ring_set_wptr(ring);
312+
ring->sched.ready = true;
313+
}
314+
}
315+
} else {
316+
for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
317+
jpeg_inst = GET_INST(JPEG, i);
190318

191-
if (ring->use_doorbell)
192-
adev->nbio.funcs->vcn_doorbell_range(
193-
adev, ring->use_doorbell,
194-
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
195-
9 * jpeg_inst,
196-
adev->jpeg.inst[i].aid_id);
319+
ring = adev->jpeg.inst[i].ring_dec;
197320

198-
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
199-
ring = &adev->jpeg.inst[i].ring_dec[j];
200321
if (ring->use_doorbell)
201-
WREG32_SOC15_OFFSET(
202-
VCN, GET_INST(VCN, i),
203-
regVCN_JPEG_DB_CTRL,
204-
(ring->pipe ? (ring->pipe - 0x15) : 0),
205-
ring->doorbell_index
322+
adev->nbio.funcs->vcn_doorbell_range(
323+
adev, ring->use_doorbell,
324+
(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
325+
9 * jpeg_inst,
326+
adev->jpeg.inst[i].aid_id);
327+
328+
for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
329+
ring = &adev->jpeg.inst[i].ring_dec[j];
330+
if (ring->use_doorbell)
331+
WREG32_SOC15_OFFSET(
332+
VCN, GET_INST(VCN, i),
333+
regVCN_JPEG_DB_CTRL,
334+
(ring->pipe ? (ring->pipe - 0x15) : 0),
335+
ring->doorbell_index
206336
<< VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
207-
VCN_JPEG_DB_CTRL__EN_MASK);
208-
r = amdgpu_ring_test_helper(ring);
209-
if (r)
210-
return r;
337+
VCN_JPEG_DB_CTRL__EN_MASK);
338+
r = amdgpu_ring_test_helper(ring);
339+
if (r)
340+
return r;
341+
}
211342
}
212343
}
213344
DRM_DEV_INFO(adev->dev, "JPEG decode initialized successfully.\n");

0 commit comments

Comments
 (0)