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

Boyuan Zhang boyzhang at amd.com
Fri Jun 1 21:25:56 UTC 2018



On 2018-06-01 01:54 PM, Christian König wrote:
> Am 01.06.2018 um 18:35 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.
>>
>> 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)
>
> &ptr only works in C++, you need to use *ptr here :)
>
> But apart from that the patch now looks good to me,
> Christian.

Oops, sorry my fault. I've no idea why I made this obvious mistake. This 
is totally accidental... Anyways, just sent out patch#9 v4.

>
>> +{
>> +    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))) {
>> +        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,
>



More information about the amd-gfx mailing list