[PATCH 09/18] drm/amdgpu: implement patch for fixing a known bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am 01.06.2018 um 23:24 schrieb boyuan.zhang at amd.com:
> From: Boyuan Zhang <boyuan.zhang at amd.com>
>
> Implement a patch to maunally reset read pointer
>
> v2: using ring assignment instead of amdgpu_ring_write. adding comments
> for each steps in the patch function.
> v3: fixing a typo bug.
> v4: fixing a bug in v3.
>
> Signed-off-by: Boyuan Zhang <boyuan.zhang at amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 92 +++++++++++++++++++++++++++++++++++
>   1 file changed, 92 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> index ea1d677..e8d24a6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
> @@ -40,6 +40,7 @@ static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
>   static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);
>   static void vcn_v1_0_set_jpeg_ring_funcs(struct amdgpu_device *adev);
>   static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev);
> +static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr);
>   
>   /**
>    * vcn_v1_0_early_init - set function pointers
> @@ -1442,6 +1443,97 @@ static void vcn_v1_0_jpeg_ring_nop(struct amdgpu_ring *ring, uint32_t count)
>   	}
>   }
>   
> +static void vcn_v1_0_jpeg_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val)
> +{
> +	struct amdgpu_device *adev = ring->adev;
> +	ring->ring[(*ptr)++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
> +	if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
> +				((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {

Looks like you are using way to many tabs here. Same problem below.

Apart from that the patch is Reviewed-by: Christian König 
<christian.koenig at amd.com>.

Regards,
Christian.

> +		ring->ring[(*ptr)++] = 0;
> +		ring->ring[(*ptr)++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0);
> +	} else {
> +		ring->ring[(*ptr)++] = reg_offset;
> +		ring->ring[(*ptr)++] = PACKETJ(0, 0, 0, PACKETJ_TYPE0);
> +	}
> +	ring->ring[(*ptr)++] = val;
> +}
> +
> +static void vcn_v1_0_jpeg_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr)
> +{
> +	struct amdgpu_device *adev = ring->adev;
> +
> +	uint32_t reg, reg_offset, val, mask, i;
> +
> +	// 1st: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW
> +	reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW);
> +	reg_offset = (reg << 2);
> +	val = lower_32_bits(ring->gpu_addr);
> +	vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
> +
> +	// 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH
> +	reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH);
> +	reg_offset = (reg << 2);
> +	val = upper_32_bits(ring->gpu_addr);
> +	vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
> +
> +	// 3rd to 5th: issue MEM_READ commands
> +	for (i = 0; i <= 2; i++) {
> +		ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE2);
> +		ring->ring[ptr++] = 0;
> +	}
> +
> +	// 6th: program mmUVD_JRBC_RB_CNTL register to enable NO_FETCH and RPTR write ability
> +	reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL);
> +	reg_offset = (reg << 2);
> +	val = 0x13;
> +	vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
> +
> +	// 7th: program mmUVD_JRBC_RB_REF_DATA
> +	reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA);
> +	reg_offset = (reg << 2);
> +	val = 0x1;
> +	vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
> +
> +	// 8th: issue conditional register read mmUVD_JRBC_RB_CNTL
> +	reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL);
> +	reg_offset = (reg << 2);
> +	val = 0x1;
> +	mask = 0x1;
> +
> +	ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0);
> +	ring->ring[ptr++] = 0x01400200;
> +	ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0);
> +	ring->ring[ptr++] = val;
> +	ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
> +	if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
> +			((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
> +		ring->ring[ptr++] = 0;
> +		ring->ring[ptr++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3);
> +	} else {
> +		ring->ring[ptr++] = reg_offset;
> +		ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE3);
> +	}
> +	ring->ring[ptr++] = mask;
> +
> +	//9th to 21st: insert no-op
> +	for (i = 0; i <= 12; i++) {
> +		ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
> +		ring->ring[ptr++] = 0;
> +	}
> +
> +	//22nd: reset mmUVD_JRBC_RB_RPTR
> +	reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_RPTR);
> +	reg_offset = (reg << 2);
> +	val = 0;
> +	vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
> +
> +	//23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch
> +	reg = SOC15_REG_OFFSET(UVD, 0, mmUVD_JRBC_RB_CNTL);
> +	reg_offset = (reg << 2);
> +	val = 0x12;
> +	vcn_v1_0_jpeg_ring_patch_wreg(ring, &ptr, reg_offset, val);
> +}
> +
>   static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev,
>   					struct amdgpu_irq_src *source,
>   					unsigned type,



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux