[PATCH v2 1/2] drm/amdgpu: enhance amdgpu_vcn_suspend

Leo Liu leo.liu at amd.com
Mon May 17 17:43:02 UTC 2021


On 2021-05-17 12:54 p.m., James Zhu wrote:
> I am wondering if there are still some jobs kept in the queue, it is 
> lucky to check

Yes it's possible, in this case delayed handler is set, so cancelling 
once is enough.


>
> UVD_POWER_STATUS done, but after, fw start a new job that list in the 
> queue.
>
> To handle this situation perfectly, we need add mechanism to suspend 
> fw first.

I think that should be handled by the sequence from 
vcn_v3_0_stop_dpg_mode().


>
> Another case, if it is unlucky, that  vcn fw hung at that time, 
> UVD_POWER_STATUS
>
> always keeps busy.   then it needs force powering gate the vcn hw 
> after certain time waiting.

Yep, we still need to gate VCN power after certain timeout.


Regards,

Leo



>
> Best Regards!
>
> James
>
> On 2021-05-17 12:34 p.m., Leo Liu wrote:
>>
>> On 2021-05-17 11:52 a.m., James Zhu wrote:
>>> During vcn suspends, stop ring continue to receive new requests,
>>> and try to wait for all vcn jobs to finish gracefully.
>>>
>>> v2: Forced powering gate vcn hardware after few wainting retry.
>>>
>>> Signed-off-by: James Zhu <James.Zhu at amd.com>
>>> ---
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 22 +++++++++++++++++++++-
>>>   1 file changed, 21 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
>>> index 2016459..9f3a6e7 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
>>> @@ -275,9 +275,29 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
>>>   {
>>>       unsigned size;
>>>       void *ptr;
>>> +    int retry_max = 6;
>>>       int i;
>>>   -    cancel_delayed_work_sync(&adev->vcn.idle_work);
>>> +    for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
>>> +        if (adev->vcn.harvest_config & (1 << i))
>>> +            continue;
>>> +        ring = &adev->vcn.inst[i].ring_dec;
>>> +        ring->sched.ready = false;
>>> +
>>> +        for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
>>> +            ring = &adev->vcn.inst[i].ring_enc[j];
>>> +            ring->sched.ready = false;
>>> +        }
>>> +    }
>>> +
>>> +    while (retry_max-- && 
>>> cancel_delayed_work_sync(&adev->vcn.idle_work))
>>> +        mdelay(5);
>>
>> I think it's possible to have one pending job unprocessed with VCN 
>> when suspend sequence getting here, but it shouldn't be more than 
>> one, cancel_delayed_work_sync probably return false after the first 
>> time, so calling cancel_delayed_work_sync once should be enough here. 
>> we probably need to wait longer from:
>>
>> SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
>>         UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
>>
>> to make sure the unprocessed job get done.
>>
>>
>> Regards,
>>
>> Leo
>>
>>
>>> +    if (!retry_max && !amdgpu_sriov_vf(adev)) {
>>> +        if (RREG32_SOC15(VCN, i, mmUVD_STATUS)) {
>>> +            dev_warn(adev->dev, "Forced powering gate vcn hardware!");
>>> +            vcn_v3_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
>>> +        }
>>> +    }
>>>         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
>>>           if (adev->vcn.harvest_config & (1 << i))


More information about the amd-gfx mailing list