Skip to content

Commit

Permalink
drm/amdgpu: fix sdma doorbell init ordering on APUs
Browse files Browse the repository at this point in the history
commit 50b0e4d upstream.

Commit 8795e18 ("PCI/portdrv: Don't disable AER reporting in get_port_device_capability()")
uncovered a bug in amdgpu that required a reordering of the driver
init sequence to avoid accessing a special register on the GPU
before it was properly set up leading to an PCI AER error.  This
reordering uncovered a different hw programming ordering dependency
in some APUs where the SDMA doorbells need to be programmed before
the GFX doorbells. To fix this, move the SDMA doorbell programming
back into the soc15 common code, but use the actual doorbell range
values directly rather than the values stored in the ring structure
since those will not be initialized at this point.

This is a partial revert, but with the doorbell assignment
fixed so the proper doorbell index is set before it's used.

Fixes: e3163bc ("drm/amdgpu: move nbio sdma_doorbell_range() into sdma code for vega")
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: skhan@linuxfoundation.org
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
alexdeucher authored and gregkh committed Oct 29, 2022
1 parent b6ea267 commit 3e2c60d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
5 changes: 0 additions & 5 deletions drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
Expand Up @@ -1504,11 +1504,6 @@ static int sdma_v4_0_start(struct amdgpu_device *adev)
WREG32_SDMA(i, mmSDMA0_CNTL, temp);

if (!amdgpu_sriov_vf(adev)) {
ring = &adev->sdma.instance[i].ring;
adev->nbio.funcs->sdma_doorbell_range(adev, i,
ring->use_doorbell, ring->doorbell_index,
adev->doorbell_index.sdma_doorbell_range);

/* unhalt engine */
temp = RREG32_SDMA(i, mmSDMA0_F32_CNTL);
temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0);
Expand Down
21 changes: 21 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/soc15.c
Expand Up @@ -1211,6 +1211,20 @@ static int soc15_common_sw_fini(void *handle)
return 0;
}

static void soc15_sdma_doorbell_range_init(struct amdgpu_device *adev)
{
int i;

/* sdma doorbell range is programed by hypervisor */
if (!amdgpu_sriov_vf(adev)) {
for (i = 0; i < adev->sdma.num_instances; i++) {
adev->nbio.funcs->sdma_doorbell_range(adev, i,
true, adev->doorbell_index.sdma_engine[i] << 1,
adev->doorbell_index.sdma_doorbell_range);
}
}
}

static int soc15_common_hw_init(void *handle)
{
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
Expand All @@ -1230,6 +1244,13 @@ static int soc15_common_hw_init(void *handle)

/* enable the doorbell aperture */
soc15_enable_doorbell_aperture(adev, true);
/* HW doorbell routing policy: doorbell writing not
* in SDMA/IH/MM/ACV range will be routed to CP. So
* we need to init SDMA doorbell range prior
* to CP ip block init and ring test. IH already
* happens before CP.
*/
soc15_sdma_doorbell_range_init(adev);

return 0;
}
Expand Down

0 comments on commit 3e2c60d

Please sign in to comment.