<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div dir="auto">
<div>I think we should implement the write/wait combined command in gfx10.</div>
<div dir="auto"><br>
</div>
<div dir="auto">Did we ever released any firmware which couldn't do this?</div>
<div dir="auto"><br>
</div>
<div dir="auto">Christian.<br>
<div class="gmail_extra" dir="auto"><br>
<div class="gmail_quote">Am 28.10.2019 13:07 schrieb "Zhu, Changfeng" <Changfeng.Zhu@amd.com>:<br type="attribution">
<blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><font size="2"><span style="font-size:11pt">
<div>Hi Christian,<br>
<br>
Should we also realize the function of gfx_v9_0_wait_reg_mem in gfx10 like gfx9 since gfx10 also realize write/wait command in a single packet after CL#1761300?<br>
<br>
Or we can add dummy read in gmc10 by using emit_wait like Luben's way?<br>
<br>
BR,<br>
Changfeng. <br>
<br>
-----Original Message-----<br>
From: Koenig, Christian <Christian.Koenig@amd.com> <br>
Sent: Monday, October 28, 2019 6:47 PM<br>
To: Zhu, Changfeng <Changfeng.Zhu@amd.com>; amd-gfx@lists.freedesktop.org<br>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Pelloux-prayer, Pierre-eric <Pierre-eric.Pelloux-prayer@amd.com>; Huang, Ray <Ray.Huang@amd.com>; Tuikov, Luben <Luben.Tuikov@amd.com><br>
Subject: Re: [PATCH] drm/amdgpu: GFX9, GFX10: GRBM requires 1-cycle delay<br>
<br>
Hi Changfeng,<br>
<br>
> So how can we deal with the firmware between mec version(402) and mec version(421)?<br>
Well of hand I see only two options: Either print a warning or completely reject loading the driver.<br>
<br>
Completely rejecting loading the driver is probably not a good idea and the issue is actually extremely unlikely to cause any problems.<br>
<br>
So printing a warning that the user should update their firmware is probably the best approach.<br>
<br>
Regards,<br>
Christian.<br>
<br>
Am 28.10.19 um 04:01 schrieb Zhu, Changfeng:<br>
> Hi Christian,<br>
><br>
> Re- that won't work, you can't add this to <br>
> amdgpu_ring_emit_reg_write_reg_wait_helper or break all read triggered registers (like the semaphore ones).<br>
><br>
> Do you mean that I should use reg_wait registers(wait_reg_mem) like Luben to replace read triggered registers for adding dummy read?<br>
><br>
> Re-Additional to that it will never work on GFX9, since the CP firmware there uses the integrated write/wait command and you can't add an additional dummy read there.<br>
><br>
> Yes, I see the integrated write/wait command and they are realized in gfx_v9_0_wait_reg_mem:<br>
> Emily's patch:<br>
> drm/amdgpu: Remove the sriov checking and add firmware checking <br>
> decides when to go into gfx_v9_0_wait_reg_mem and when go into amdgpu_ring_emit_reg_write_reg_wait_helper.<br>
><br>
> However there are two problems now.<br>
> 1.Before the fw_version_ok fw version, the code goes into amdgpu_ring_emit_reg_write_reg_wait_helper. In this case, should not we add dummy read in amdgpu_ring_emit_reg_write_reg_wait_helper?<br>
> 2.After the fw_version_ok fw version, the code goes into gfx_v9_0_wait_reg_mem. However, it realizes write/wait command in firmware. Then how can we add this dummy read? According to Yang,Zilong, the CP firmware has realized dummy in firmware in CL:<br>
> Vega20 CL#1762470 @3/27/2019<br>
> Navi10 CL#1761300 @3/25/2019<br>
> Accodring to CL#1762470,<br>
> The firmware which realized dummy read is(Raven for example):<br>
> Mec version:<br>
> #define F32_MEC_UCODE_VERSION "#421"<br>
> #define F32_MEC_FEATURE_VERSION 46<br>
> Pfp version:<br>
> #define F32_PFP_UCODE_VERSION "#183"<br>
> #define F32_PFP_FEATURE_VERSION 46<br>
> In Emily's patch:<br>
> The CP firmware whichuses the integrated write/wait command begins from version:<br>
> +       case CHIP_RAVEN:<br>
> +               if ((adev->gfx.me_fw_version >= 0x0000009c) &&<br>
> +                   (adev->gfx.me_feature_version >= 42) &&<br>
> +                   (adev->gfx.pfp_fw_version >=  0x000000b1(177)) &&<br>
> +                   (adev->gfx.pfp_feature_version >= 42))<br>
> +                       adev->gfx.me_fw_write_wait = true;<br>
> +<br>
> +               if ((adev->gfx.mec_fw_version >=  0x00000192(402)) &&<br>
> +                   (adev->gfx.mec_feature_version >= 42))<br>
> +                       adev->gfx.mec_fw_write_wait = true;<br>
> +               break;<br>
><br>
> So how can we deal with the firmware between mec version(402) and mec version(421)?<br>
> It will realize write/wait command in CP firmware but it doesn't have dummy read.<br>
><br>
> BR,<br>
> Changfeng.<br>
><br>
> -----Original Message-----<br>
> From: Koenig, Christian <Christian.Koenig@amd.com><br>
> Sent: Friday, October 25, 2019 11:54 PM<br>
> To: Zhu, Changfeng <Changfeng.Zhu@amd.com>; <br>
> amd-gfx@lists.freedesktop.org<br>
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Pelloux-prayer, <br>
> Pierre-eric <Pierre-eric.Pelloux-prayer@amd.com>; Huang, Ray <br>
> <Ray.Huang@amd.com>; Tuikov, Luben <Luben.Tuikov@amd.com><br>
> Subject: Re: [PATCH] drm/amdgpu: GFX9, GFX10: GRBM requires 1-cycle <br>
> delay<br>
><br>
> Hi Changfeng,<br>
><br>
> that won't work, you can't add this to <br>
> amdgpu_ring_emit_reg_write_reg_wait_helper or break all read triggered registers (like the semaphore ones).<br>
><br>
> Additional to that it will never work on GFX9, since the CP firmware there uses the integrated write/wait command and you can't add an additional dummy read there.<br>
><br>
> Regards,<br>
> Christian.<br>
><br>
> Am 25.10.19 um 16:22 schrieb Zhu, Changfeng:<br>
>> I try to write a patch based on the patch of Tuikov,Luben.<br>
>><br>
>> Inspired by Luben,here is the patch:<br>
>><br>
>>   From 1980d8f1ed44fb9a84a5ea1f6e2edd2bc25c629a Mon Sep 17 00:00:00<br>
>> 2001<br>
>> From: changzhu <Changfeng.Zhu@amd.com><br>
>> Date: Thu, 10 Oct 2019 11:02:33 +0800<br>
>> Subject: [PATCH] drm/amdgpu: add dummy read by engines for some GCVM status<br>
>>    registers<br>
>><br>
>> The GRBM register interface is now capable of bursting 1 cycle per <br>
>> register wr->wr, wr->rd much faster than previous muticycle per <br>
>> transaction done interface.  This has caused a problem where status <br>
>> registers requiring HW to update have a 1 cycle delay, due to the <br>
>> register update having to go through GRBM.<br>
>><br>
>> SW may operate on an incorrect value if they write a register and <br>
>> immediately check the corresponding status register.<br>
>><br>
>> Registers requiring HW to clear or set fields may be delayed by 1 cycle.<br>
>> For example,<br>
>><br>
>> 1. write VM_INVALIDATE_ENG0_REQ mask = 5a 2. read <br>
>> VM_INVALIDATE_ENG0_ACKb till the ack is same as the request mask = 5a<br>
>>               a. HW will reset VM_INVALIDATE_ENG0_ACK = 0 until invalidation <br>
>> is complete 3. write VM_INVALIDATE_ENG0_REQ mask = 5a 4. read <br>
>> VM_INVALIDATE_ENG0_ACK till the ack is same as the request mask = 5a<br>
>>       a. First read of VM_INVALIDATE_ENG0_ACK = 5a instead of 0<br>
>>       b. Second read of VM_INVALIDATE_ENG0_ACK = 0 because the remote GRBM h/w<br>
>>          register takes one extra cycle to be cleared<br>
>>       c. In this case,SW wil see a false ACK if they exit on first read<br>
>><br>
>> Affected registers (only GC variant)  | Recommended Dummy Read<br>
>> --------------------------------------+----------------------------<br>
>> VM_INVALIDATE_ENG*_ACK                     |  VM_INVALIDATE_ENG*_REQ<br>
>> VM_L2_STATUS                       |  VM_L2_STATUS<br>
>> VM_L2_PROTECTION_FAULT_STATUS              |  VM_L2_PROTECTION_FAULT_STATUS<br>
>> VM_L2_PROTECTION_FAULT_ADDR_HI/LO32   |  VM_L2_PROTECTION_FAULT_ADDR_HI/LO32<br>
>> VM_L2_IH_LOG_BUSY                  |  VM_L2_IH_LOG_BUSY<br>
>> MC_VM_L2_PERFCOUNTER_HI/LO         |  MC_VM_L2_PERFCOUNTER_HI/LO<br>
>> ATC_L2_PERFCOUNTER_HI/LO           |  ATC_L2_PERFCOUNTER_HI/LO<br>
>> ATC_L2_PERFCOUNTER2_HI/LO          |  ATC_L2_PERFCOUNTER2_HI/LO<br>
>><br>
>> It also needs dummy read by engines for these gc registers.<br>
>><br>
>> Change-Id: Ie028f37eb789966d4593984bd661b248ebeb1ac3<br>
>> Signed-off-by: changzhu <Changfeng.Zhu@amd.com><br>
>> ---<br>
>>    drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c |  5 +++++<br>
>>    drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c   |  2 ++<br>
>>    drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c    |  2 ++<br>
>>    drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c   |  4 ++++<br>
>>    drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c   | 18 ++++++++++++++++++<br>
>>    5 files changed, 31 insertions(+)<br>
>><br>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c<br>
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c<br>
>> index 4b3f58dbf36f..c2fbf6087ecf 100644<br>
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c<br>
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c<br>
>> @@ -392,6 +392,11 @@ void amdgpu_ring_emit_reg_write_reg_wait_helper(struct amdgpu_ring *ring,<br>
>>                                               uint32_t ref, uint32_t mask)<br>
>>    {<!-- --><br>
>>       amdgpu_ring_emit_wreg(ring, reg0, ref);<br>
>> +<br>
>> +    /* wait for a cycle to reset vm_inv_eng0_ack */<br>
>> +    if (ring->funcs->vmhub == AMDGPU_GFXHUB_0)<br>
>> +            amdgpu_ring_emit_rreg(ring, reg0);<br>
>> +<br>
>>       amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);<br>
>>    }<br>
>>    <br>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c<br>
>> b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c<br>
>> index ef1975a5323a..104c47734316 100644<br>
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c<br>
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c<br>
>> @@ -5155,6 +5155,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {<!-- --><br>
>>       .patch_cond_exec = gfx_v10_0_ring_emit_patch_cond_exec,<br>
>>       .preempt_ib = gfx_v10_0_ring_preempt_ib,<br>
>>       .emit_tmz = gfx_v10_0_ring_emit_tmz,<br>
>> +    .emit_rreg = gfx_v10_0_ring_emit_rreg,<br>
>>       .emit_wreg = gfx_v10_0_ring_emit_wreg,<br>
>>       .emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,<br>
>>    };<br>
>> @@ -5188,6 +5189,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {<!-- --><br>
>>       .test_ib = gfx_v10_0_ring_test_ib,<br>
>>       .insert_nop = amdgpu_ring_insert_nop,<br>
>>       .pad_ib = amdgpu_ring_generic_pad_ib,<br>
>> +    .emit_rreg = gfx_v10_0_ring_emit_rreg,<br>
>>       .emit_wreg = gfx_v10_0_ring_emit_wreg,<br>
>>       .emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,<br>
>>    };<br>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c<br>
>> b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c<br>
>> index 2f03bf533d41..d00b53de0fdc 100644<br>
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c<br>
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c<br>
>> @@ -6253,6 +6253,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {<!-- --><br>
>>       .init_cond_exec = gfx_v9_0_ring_emit_init_cond_exec,<br>
>>       .patch_cond_exec = gfx_v9_0_ring_emit_patch_cond_exec,<br>
>>       .emit_tmz = gfx_v9_0_ring_emit_tmz,<br>
>> +    .emit_rreg = gfx_v9_0_ring_emit_rreg,<br>
>>       .emit_wreg = gfx_v9_0_ring_emit_wreg,<br>
>>       .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,<br>
>>       .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,<br>
>> @@ -6289,6 +6290,7 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = {<!-- --><br>
>>       .insert_nop = amdgpu_ring_insert_nop,<br>
>>       .pad_ib = amdgpu_ring_generic_pad_ib,<br>
>>       .set_priority = gfx_v9_0_ring_set_priority_compute,<br>
>> +    .emit_rreg = gfx_v9_0_ring_emit_rreg,<br>
>>       .emit_wreg = gfx_v9_0_ring_emit_wreg,<br>
>>       .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait,<br>
>>       .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait,<br>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c<br>
>> b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c<br>
>> index 3b00bce14cfb..dce6b651da1f 100644<br>
>> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c<br>
>> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c<br>
>> @@ -346,6 +346,10 @@ static uint64_t<br>
>> gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,<br>
>>    <br>
>>       amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_req + eng, req);<br>
>>    <br>
>> +    /* wait for a cycle to reset vm_inv_eng0_ack */<br>
>> +    if (ring->funcs->vmhub == AMDGPU_GFXHUB_0)<br>
>> +            amdgpu_ring_emit_rreg(ring, hub->vm_inv_eng0_req + eng);<br>
>> +<br>
>>       /* wait for the invalidate to complete */<br>
>>       amdgpu_ring_emit_reg_wait(ring, hub->vm_inv_eng0_ack + eng,<br>
>>                                 1 << vmid, 1 << vmid);<br>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c<br>
>> b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c<br>
>> index 3460c00f3eaa..baaa33467882 100644<br>
>> --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c<br>
>> +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c<br>
>> @@ -38,6 +38,7 @@<br>
>>    #include "navi10_sdma_pkt_open.h"<br>
>>    #include "nbio_v2_3.h"<br>
>>    #include "sdma_v5_0.h"<br>
>> +#include "nvd.h"<br>
>>    <br>
>>    MODULE_FIRMWARE("amdgpu/navi10_sdma.bin");<br>
>>    MODULE_FIRMWARE("amdgpu/navi10_sdma1.bin");<br>
>> @@ -1147,6 +1148,22 @@ static void sdma_v5_0_ring_emit_vm_flush(struct amdgpu_ring *ring,<br>
>>       amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);<br>
>>    }<br>
>>    <br>
>> +static void sdma_v5_0_ring_emit_rreg(struct amdgpu_ring *ring, <br>
>> +uint32_t reg) {<!-- --><br>
>> +    struct amdgpu_device *adev = ring->adev;<br>
>> +<br>
>> +    amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));<br>
>> +    amdgpu_ring_write(ring, 0 | /* src: register*/<br>
>> +                            (5 << 8) |  /* dst: memory */<br>
>> +                            (1 << 20)); /* write confirm */<br>
>> +    amdgpu_ring_write(ring, reg);<br>
>> +    amdgpu_ring_write(ring, 0);<br>
>> +    amdgpu_ring_write(ring, lower_32_bits(adev->wb.gpu_addr +<br>
>> +                            adev->virt.reg_val_offs * 4));<br>
>> +    amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +<br>
>> +                            adev->virt.reg_val_offs * 4));<br>
>> +}<br>
>> +<br>
>>    static void sdma_v5_0_ring_emit_wreg(struct amdgpu_ring *ring,<br>
>>                                    uint32_t reg, uint32_t val)<br>
>>    {<!-- --><br>
>> @@ -1597,6 +1614,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {<!-- --><br>
>>       .test_ib = sdma_v5_0_ring_test_ib,<br>
>>       .insert_nop = sdma_v5_0_ring_insert_nop,<br>
>>       .pad_ib = sdma_v5_0_ring_pad_ib,<br>
>> +    .emit_rreg = sdma_v5_0_ring_emit_rreg,<br>
>>       .emit_wreg = sdma_v5_0_ring_emit_wreg,<br>
>>       .emit_reg_wait = sdma_v5_0_ring_emit_reg_wait,<br>
>>       .init_cond_exec = sdma_v5_0_ring_init_cond_exec,<br>
<br>
</div>
</span></font></div>
</blockquote>
</div>
<br>
</div>
</div>
</div>
</body>
</html>