Commit c01b6a1d authored by James Zhu's avatar James Zhu Committed by Alex Deucher

drm/amdgpu: modify amdgpu_vcn to support multiple instances

Arcturus has dual-VCN. Need Restruct amdgpu_device::vcn to support
multiple vcns. There are no any logical changes here
Signed-off-by: default avatarJames Zhu <James.Zhu@amd.com>
Reviewed-by: default avatarLeo Liu <leo.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 989b6a05
...@@ -154,15 +154,15 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, ...@@ -154,15 +154,15 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
num_rings = 1; num_rings = 1;
break; break;
case AMDGPU_HW_IP_VCN_DEC: case AMDGPU_HW_IP_VCN_DEC:
rings[0] = &adev->vcn.ring_dec; rings[0] = &adev->vcn.inst[0].ring_dec;
num_rings = 1; num_rings = 1;
break; break;
case AMDGPU_HW_IP_VCN_ENC: case AMDGPU_HW_IP_VCN_ENC:
rings[0] = &adev->vcn.ring_enc[0]; rings[0] = &adev->vcn.inst[0].ring_enc[0];
num_rings = 1; num_rings = 1;
break; break;
case AMDGPU_HW_IP_VCN_JPEG: case AMDGPU_HW_IP_VCN_JPEG:
rings[0] = &adev->vcn.ring_jpeg; rings[0] = &adev->vcn.inst[0].ring_jpeg;
num_rings = 1; num_rings = 1;
break; break;
} }
......
...@@ -408,7 +408,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, ...@@ -408,7 +408,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
break; break;
case AMDGPU_HW_IP_VCN_DEC: case AMDGPU_HW_IP_VCN_DEC:
type = AMD_IP_BLOCK_TYPE_VCN; type = AMD_IP_BLOCK_TYPE_VCN;
if (adev->vcn.ring_dec.sched.ready) if (adev->vcn.inst[0].ring_dec.sched.ready)
++num_rings; ++num_rings;
ib_start_alignment = 16; ib_start_alignment = 16;
ib_size_alignment = 16; ib_size_alignment = 16;
...@@ -416,14 +416,14 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev, ...@@ -416,14 +416,14 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
case AMDGPU_HW_IP_VCN_ENC: case AMDGPU_HW_IP_VCN_ENC:
type = AMD_IP_BLOCK_TYPE_VCN; type = AMD_IP_BLOCK_TYPE_VCN;
for (i = 0; i < adev->vcn.num_enc_rings; i++) for (i = 0; i < adev->vcn.num_enc_rings; i++)
if (adev->vcn.ring_enc[i].sched.ready) if (adev->vcn.inst[0].ring_enc[i].sched.ready)
++num_rings; ++num_rings;
ib_start_alignment = 64; ib_start_alignment = 64;
ib_size_alignment = 1; ib_size_alignment = 1;
break; break;
case AMDGPU_HW_IP_VCN_JPEG: case AMDGPU_HW_IP_VCN_JPEG:
type = AMD_IP_BLOCK_TYPE_VCN; type = AMD_IP_BLOCK_TYPE_VCN;
if (adev->vcn.ring_jpeg.sched.ready) if (adev->vcn.inst[0].ring_jpeg.sched.ready)
++num_rings; ++num_rings;
ib_start_alignment = 16; ib_start_alignment = 16;
ib_size_alignment = 16; ib_size_alignment = 16;
......
...@@ -147,8 +147,8 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) ...@@ -147,8 +147,8 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8); bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE, r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.vcpu_bo, AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[0].vcpu_bo,
&adev->vcn.gpu_addr, &adev->vcn.cpu_addr); &adev->vcn.inst[0].gpu_addr, &adev->vcn.inst[0].cpu_addr);
if (r) { if (r) {
dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r); dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
return r; return r;
...@@ -171,7 +171,7 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) ...@@ -171,7 +171,7 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
{ {
int i; int i;
kvfree(adev->vcn.saved_bo); kvfree(adev->vcn.inst[0].saved_bo);
if (adev->vcn.indirect_sram) { if (adev->vcn.indirect_sram) {
amdgpu_bo_free_kernel(&adev->vcn.dpg_sram_bo, amdgpu_bo_free_kernel(&adev->vcn.dpg_sram_bo,
...@@ -179,16 +179,16 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) ...@@ -179,16 +179,16 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
(void **)&adev->vcn.dpg_sram_cpu_addr); (void **)&adev->vcn.dpg_sram_cpu_addr);
} }
amdgpu_bo_free_kernel(&adev->vcn.vcpu_bo, amdgpu_bo_free_kernel(&adev->vcn.inst[0].vcpu_bo,
&adev->vcn.gpu_addr, &adev->vcn.inst[0].gpu_addr,
(void **)&adev->vcn.cpu_addr); (void **)&adev->vcn.inst[0].cpu_addr);
amdgpu_ring_fini(&adev->vcn.ring_dec); amdgpu_ring_fini(&adev->vcn.inst[0].ring_dec);
for (i = 0; i < adev->vcn.num_enc_rings; ++i) for (i = 0; i < adev->vcn.num_enc_rings; ++i)
amdgpu_ring_fini(&adev->vcn.ring_enc[i]); amdgpu_ring_fini(&adev->vcn.inst[0].ring_enc[i]);
amdgpu_ring_fini(&adev->vcn.ring_jpeg); amdgpu_ring_fini(&adev->vcn.inst[0].ring_jpeg);
release_firmware(adev->vcn.fw); release_firmware(adev->vcn.fw);
...@@ -202,17 +202,17 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev) ...@@ -202,17 +202,17 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
cancel_delayed_work_sync(&adev->vcn.idle_work); cancel_delayed_work_sync(&adev->vcn.idle_work);
if (adev->vcn.vcpu_bo == NULL) if (adev->vcn.inst[0].vcpu_bo == NULL)
return 0; return 0;
size = amdgpu_bo_size(adev->vcn.vcpu_bo); size = amdgpu_bo_size(adev->vcn.inst[0].vcpu_bo);
ptr = adev->vcn.cpu_addr; ptr = adev->vcn.inst[0].cpu_addr;
adev->vcn.saved_bo = kvmalloc(size, GFP_KERNEL); adev->vcn.inst[0].saved_bo = kvmalloc(size, GFP_KERNEL);
if (!adev->vcn.saved_bo) if (!adev->vcn.inst[0].saved_bo)
return -ENOMEM; return -ENOMEM;
memcpy_fromio(adev->vcn.saved_bo, ptr, size); memcpy_fromio(adev->vcn.inst[0].saved_bo, ptr, size);
return 0; return 0;
} }
...@@ -222,16 +222,16 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) ...@@ -222,16 +222,16 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
unsigned size; unsigned size;
void *ptr; void *ptr;
if (adev->vcn.vcpu_bo == NULL) if (adev->vcn.inst[0].vcpu_bo == NULL)
return -EINVAL; return -EINVAL;
size = amdgpu_bo_size(adev->vcn.vcpu_bo); size = amdgpu_bo_size(adev->vcn.inst[0].vcpu_bo);
ptr = adev->vcn.cpu_addr; ptr = adev->vcn.inst[0].cpu_addr;
if (adev->vcn.saved_bo != NULL) { if (adev->vcn.inst[0].saved_bo != NULL) {
memcpy_toio(ptr, adev->vcn.saved_bo, size); memcpy_toio(ptr, adev->vcn.inst[0].saved_bo, size);
kvfree(adev->vcn.saved_bo); kvfree(adev->vcn.inst[0].saved_bo);
adev->vcn.saved_bo = NULL; adev->vcn.inst[0].saved_bo = NULL;
} else { } else {
const struct common_firmware_header *hdr; const struct common_firmware_header *hdr;
unsigned offset; unsigned offset;
...@@ -239,7 +239,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) ...@@ -239,7 +239,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev)
hdr = (const struct common_firmware_header *)adev->vcn.fw->data; hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
offset = le32_to_cpu(hdr->ucode_array_offset_bytes); offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
memcpy_toio(adev->vcn.cpu_addr, adev->vcn.fw->data + offset, memcpy_toio(adev->vcn.inst[0].cpu_addr, adev->vcn.fw->data + offset,
le32_to_cpu(hdr->ucode_size_bytes)); le32_to_cpu(hdr->ucode_size_bytes));
size -= le32_to_cpu(hdr->ucode_size_bytes); size -= le32_to_cpu(hdr->ucode_size_bytes);
ptr += le32_to_cpu(hdr->ucode_size_bytes); ptr += le32_to_cpu(hdr->ucode_size_bytes);
...@@ -258,7 +258,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) ...@@ -258,7 +258,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
unsigned int i; unsigned int i;
for (i = 0; i < adev->vcn.num_enc_rings; ++i) { for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]); fences += amdgpu_fence_count_emitted(&adev->vcn.inst[0].ring_enc[i]);
} }
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) { if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
...@@ -269,7 +269,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) ...@@ -269,7 +269,7 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
else else
new_state.fw_based = VCN_DPG_STATE__UNPAUSE; new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
if (amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg)) if (amdgpu_fence_count_emitted(&adev->vcn.inst[0].ring_jpeg))
new_state.jpeg = VCN_DPG_STATE__PAUSE; new_state.jpeg = VCN_DPG_STATE__PAUSE;
else else
new_state.jpeg = VCN_DPG_STATE__UNPAUSE; new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
...@@ -277,8 +277,8 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work) ...@@ -277,8 +277,8 @@ static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
adev->vcn.pause_dpg_mode(adev, &new_state); adev->vcn.pause_dpg_mode(adev, &new_state);
} }
fences += amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg); fences += amdgpu_fence_count_emitted(&adev->vcn.inst[0].ring_jpeg);
fences += amdgpu_fence_count_emitted(&adev->vcn.ring_dec); fences += amdgpu_fence_count_emitted(&adev->vcn.inst[0].ring_dec);
if (fences == 0) { if (fences == 0) {
amdgpu_gfx_off_ctrl(adev, true); amdgpu_gfx_off_ctrl(adev, true);
...@@ -312,14 +312,14 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) ...@@ -312,14 +312,14 @@ void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
unsigned int i; unsigned int i;
for (i = 0; i < adev->vcn.num_enc_rings; ++i) { for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]); fences += amdgpu_fence_count_emitted(&adev->vcn.inst[0].ring_enc[i]);
} }
if (fences) if (fences)
new_state.fw_based = VCN_DPG_STATE__PAUSE; new_state.fw_based = VCN_DPG_STATE__PAUSE;
else else
new_state.fw_based = VCN_DPG_STATE__UNPAUSE; new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
if (amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg)) if (amdgpu_fence_count_emitted(&adev->vcn.inst[0].ring_jpeg))
new_state.jpeg = VCN_DPG_STATE__PAUSE; new_state.jpeg = VCN_DPG_STATE__PAUSE;
else else
new_state.jpeg = VCN_DPG_STATE__UNPAUSE; new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
...@@ -345,7 +345,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) ...@@ -345,7 +345,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
unsigned i; unsigned i;
int r; int r;
WREG32(adev->vcn.external.scratch9, 0xCAFEDEAD); WREG32(adev->vcn.inst[0].external.scratch9, 0xCAFEDEAD);
r = amdgpu_ring_alloc(ring, 3); r = amdgpu_ring_alloc(ring, 3);
if (r) if (r)
return r; return r;
...@@ -353,7 +353,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) ...@@ -353,7 +353,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_write(ring, 0xDEADBEEF);
amdgpu_ring_commit(ring); amdgpu_ring_commit(ring);
for (i = 0; i < adev->usec_timeout; i++) { for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32(adev->vcn.external.scratch9); tmp = RREG32(adev->vcn.inst[0].external.scratch9);
if (tmp == 0xDEADBEEF) if (tmp == 0xDEADBEEF)
break; break;
udelay(1); udelay(1);
...@@ -664,7 +664,7 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) ...@@ -664,7 +664,7 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring)
unsigned i; unsigned i;
int r; int r;
WREG32(adev->vcn.external.jpeg_pitch, 0xCAFEDEAD); WREG32(adev->vcn.inst[0].external.jpeg_pitch, 0xCAFEDEAD);
r = amdgpu_ring_alloc(ring, 3); r = amdgpu_ring_alloc(ring, 3);
if (r) if (r)
return r; return r;
...@@ -674,7 +674,7 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) ...@@ -674,7 +674,7 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring)
amdgpu_ring_commit(ring); amdgpu_ring_commit(ring);
for (i = 0; i < adev->usec_timeout; i++) { for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32(adev->vcn.external.jpeg_pitch); tmp = RREG32(adev->vcn.inst[0].external.jpeg_pitch);
if (tmp == 0xDEADBEEF) if (tmp == 0xDEADBEEF)
break; break;
udelay(1); udelay(1);
...@@ -748,7 +748,7 @@ int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout) ...@@ -748,7 +748,7 @@ int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout)
} }
for (i = 0; i < adev->usec_timeout; i++) { for (i = 0; i < adev->usec_timeout; i++) {
tmp = RREG32(adev->vcn.external.jpeg_pitch); tmp = RREG32(adev->vcn.inst[0].external.jpeg_pitch);
if (tmp == 0xDEADBEEF) if (tmp == 0xDEADBEEF)
break; break;
udelay(1); udelay(1);
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#define AMDGPU_VCN_FIRMWARE_OFFSET 256 #define AMDGPU_VCN_FIRMWARE_OFFSET 256
#define AMDGPU_VCN_MAX_ENC_RINGS 3 #define AMDGPU_VCN_MAX_ENC_RINGS 3
#define AMDGPU_MAX_VCN_INSTANCES 2
#define VCN_DEC_CMD_FENCE 0x00000000 #define VCN_DEC_CMD_FENCE 0x00000000
#define VCN_DEC_CMD_TRAP 0x00000001 #define VCN_DEC_CMD_TRAP 0x00000001
#define VCN_DEC_CMD_WRITE_REG 0x00000004 #define VCN_DEC_CMD_WRITE_REG 0x00000004
...@@ -155,30 +157,38 @@ struct amdgpu_vcn_reg{ ...@@ -155,30 +157,38 @@ struct amdgpu_vcn_reg{
unsigned jpeg_pitch; unsigned jpeg_pitch;
}; };
struct amdgpu_vcn { struct amdgpu_vcn_inst {
struct amdgpu_bo *vcpu_bo; struct amdgpu_bo *vcpu_bo;
void *cpu_addr; void *cpu_addr;
uint64_t gpu_addr; uint64_t gpu_addr;
unsigned fw_version;
void *saved_bo; void *saved_bo;
struct delayed_work idle_work;
const struct firmware *fw; /* VCN firmware */
struct amdgpu_ring ring_dec; struct amdgpu_ring ring_dec;
struct amdgpu_ring ring_enc[AMDGPU_VCN_MAX_ENC_RINGS]; struct amdgpu_ring ring_enc[AMDGPU_VCN_MAX_ENC_RINGS];
struct amdgpu_ring ring_jpeg; struct amdgpu_ring ring_jpeg;
struct amdgpu_irq_src irq; struct amdgpu_irq_src irq;
struct amdgpu_vcn_reg external;
};
struct amdgpu_vcn {
unsigned fw_version;
struct delayed_work idle_work;
const struct firmware *fw; /* VCN firmware */
unsigned num_enc_rings; unsigned num_enc_rings;
enum amd_powergating_state cur_state; enum amd_powergating_state cur_state;
struct dpg_pause_state pause_state; struct dpg_pause_state pause_state;
struct amdgpu_vcn_reg internal, external;
int (*pause_dpg_mode)(struct amdgpu_device *adev,
struct dpg_pause_state *new_state);
bool indirect_sram; bool indirect_sram;
struct amdgpu_bo *dpg_sram_bo; struct amdgpu_bo *dpg_sram_bo;
void *dpg_sram_cpu_addr; void *dpg_sram_cpu_addr;
uint64_t dpg_sram_gpu_addr; uint64_t dpg_sram_gpu_addr;
uint32_t *dpg_sram_curr_addr; uint32_t *dpg_sram_curr_addr;
uint8_t num_vcn_inst;
struct amdgpu_vcn_inst inst[AMDGPU_MAX_VCN_INSTANCES];
struct amdgpu_vcn_reg internal;
int (*pause_dpg_mode)(struct amdgpu_device *adev,
struct dpg_pause_state *new_state);
}; };
int amdgpu_vcn_sw_init(struct amdgpu_device *adev); int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment