Commit b2576c3b authored by Sonny Jiang's avatar Sonny Jiang Committed by Alex Deucher

drm/amdgpu/vcn3.0: add wptr/rptr reset/update for share memory

Because of dpg, the rptr/wptr need to be saved on fw shared memory,
and restore them back in RBC_RB_RPTR/WPTR in kernel at power up.
Signed-off-by: default avatarSonny Jiang <sonny.jiang@amd.com>
Reviewed-by: default avatarLeo Liu <leo.liu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4588f7b7
...@@ -155,6 +155,7 @@ ...@@ -155,6 +155,7 @@
} \ } \
} while (0) } while (0)
#define AMDGPU_VCN_FW_SHARED_FLAG_0_RB (1 << 6)
#define AMDGPU_VCN_MULTI_QUEUE_FLAG (1 << 8) #define AMDGPU_VCN_MULTI_QUEUE_FLAG (1 << 8)
#define AMDGPU_VCN_SW_RING_FLAG (1 << 9) #define AMDGPU_VCN_SW_RING_FLAG (1 << 9)
...@@ -243,6 +244,12 @@ struct amdgpu_vcn { ...@@ -243,6 +244,12 @@ struct amdgpu_vcn {
int inst_idx, struct dpg_pause_state *new_state); int inst_idx, struct dpg_pause_state *new_state);
}; };
struct amdgpu_fw_shared_rb_ptrs_struct {
/* to WA DPG R/W ptr issues.*/
uint32_t rptr;
uint32_t wptr;
};
struct amdgpu_fw_shared_multi_queue { struct amdgpu_fw_shared_multi_queue {
uint8_t decode_queue_mode; uint8_t decode_queue_mode;
uint8_t encode_generalpurpose_queue_mode; uint8_t encode_generalpurpose_queue_mode;
...@@ -258,10 +265,12 @@ struct amdgpu_fw_shared_sw_ring { ...@@ -258,10 +265,12 @@ struct amdgpu_fw_shared_sw_ring {
struct amdgpu_fw_shared { struct amdgpu_fw_shared {
uint32_t present_flag_0; uint32_t present_flag_0;
uint8_t pad[53]; uint8_t pad[44];
struct amdgpu_fw_shared_rb_ptrs_struct rb;
uint8_t pad1[1];
struct amdgpu_fw_shared_multi_queue multi_queue; struct amdgpu_fw_shared_multi_queue multi_queue;
struct amdgpu_fw_shared_sw_ring sw_ring; struct amdgpu_fw_shared_sw_ring sw_ring;
} __attribute__((__packed__)); };
struct amdgpu_vcn_decode_buffer { struct amdgpu_vcn_decode_buffer {
uint32_t valid_buf_flag; uint32_t valid_buf_flag;
......
...@@ -238,7 +238,8 @@ static int vcn_v3_0_sw_init(void *handle) ...@@ -238,7 +238,8 @@ static int vcn_v3_0_sw_init(void *handle)
fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr;
fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SW_RING_FLAG) | fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SW_RING_FLAG) |
cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG); cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG) |
cpu_to_le32(AMDGPU_VCN_FW_SHARED_FLAG_0_RB);
fw_shared->sw_ring.is_enabled = cpu_to_le32(DEC_SW_RING_ENABLED); fw_shared->sw_ring.is_enabled = cpu_to_le32(DEC_SW_RING_ENABLED);
} }
...@@ -1074,7 +1075,13 @@ static int vcn_v3_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo ...@@ -1074,7 +1075,13 @@ static int vcn_v3_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo
WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR, WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR,
lower_32_bits(ring->wptr)); lower_32_bits(ring->wptr));
/* Reset FW shared memory RBC WPTR/RPTR */
fw_shared->rb.rptr = 0;
fw_shared->rb.wptr = lower_32_bits(ring->wptr);
/*resetting done, fw can check RB ring */
fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET); fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
/* Unstall DPG */ /* Unstall DPG */
WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
...@@ -1239,9 +1246,11 @@ static int vcn_v3_0_start(struct amdgpu_device *adev) ...@@ -1239,9 +1246,11 @@ static int vcn_v3_0_start(struct amdgpu_device *adev)
/* Initialize the ring buffer's read and write pointers */ /* Initialize the ring buffer's read and write pointers */
WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0); WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0);
WREG32_SOC15(VCN, i, mmUVD_SCRATCH2, 0);
ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR); ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR);
WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR, WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR,
lower_32_bits(ring->wptr)); lower_32_bits(ring->wptr));
fw_shared->rb.wptr = lower_32_bits(ring->wptr);
fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET); fw_shared->multi_queue.decode_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
fw_shared->multi_queue.encode_generalpurpose_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET); fw_shared->multi_queue.encode_generalpurpose_queue_mode |= cpu_to_le32(FW_QUEUE_RING_RESET);
...@@ -1662,6 +1671,10 @@ static int vcn_v3_0_pause_dpg_mode(struct amdgpu_device *adev, ...@@ -1662,6 +1671,10 @@ static int vcn_v3_0_pause_dpg_mode(struct amdgpu_device *adev,
WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
fw_shared->multi_queue.encode_lowlatency_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET); fw_shared->multi_queue.encode_lowlatency_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET);
/* restore wptr/rptr with pointers saved in FW shared memory*/
WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, fw_shared->rb.rptr);
WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR, fw_shared->rb.wptr);
/* Unstall DPG */ /* Unstall DPG */
WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
...@@ -1721,6 +1734,15 @@ static uint64_t vcn_v3_0_dec_ring_get_wptr(struct amdgpu_ring *ring) ...@@ -1721,6 +1734,15 @@ static uint64_t vcn_v3_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
static void vcn_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring) static void vcn_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
{ {
struct amdgpu_device *adev = ring->adev; struct amdgpu_device *adev = ring->adev;
volatile struct amdgpu_fw_shared *fw_shared;
if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
/*whenever update RBC_RB_WPTR, we save the wptr in shared rb.wptr and scratch2 */
fw_shared = adev->vcn.inst[ring->me].fw_shared_cpu_addr;
fw_shared->rb.wptr = lower_32_bits(ring->wptr);
WREG32_SOC15(VCN, ring->me, mmUVD_SCRATCH2,
lower_32_bits(ring->wptr));
}
if (ring->use_doorbell) { if (ring->use_doorbell) {
adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr); adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
......
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