Skip to content

Commit 50b0e4d

Browse files
committed
drm/amdgpu: fix sdma doorbell init ordering on APUs
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 <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Cc: [email protected] Cc: [email protected]
1 parent 8273b40 commit 50b0e4d

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,11 +1417,6 @@ static int sdma_v4_0_start(struct amdgpu_device *adev)
14171417
WREG32_SDMA(i, mmSDMA0_CNTL, temp);
14181418

14191419
if (!amdgpu_sriov_vf(adev)) {
1420-
ring = &adev->sdma.instance[i].ring;
1421-
adev->nbio.funcs->sdma_doorbell_range(adev, i,
1422-
ring->use_doorbell, ring->doorbell_index,
1423-
adev->doorbell_index.sdma_doorbell_range);
1424-
14251420
/* unhalt engine */
14261421
temp = RREG32_SDMA(i, mmSDMA0_F32_CNTL);
14271422
temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0);

drivers/gpu/drm/amd/amdgpu/soc15.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,20 @@ static int soc15_common_sw_fini(void *handle)
12111211
return 0;
12121212
}
12131213

1214+
static void soc15_sdma_doorbell_range_init(struct amdgpu_device *adev)
1215+
{
1216+
int i;
1217+
1218+
/* sdma doorbell range is programed by hypervisor */
1219+
if (!amdgpu_sriov_vf(adev)) {
1220+
for (i = 0; i < adev->sdma.num_instances; i++) {
1221+
adev->nbio.funcs->sdma_doorbell_range(adev, i,
1222+
true, adev->doorbell_index.sdma_engine[i] << 1,
1223+
adev->doorbell_index.sdma_doorbell_range);
1224+
}
1225+
}
1226+
}
1227+
12141228
static int soc15_common_hw_init(void *handle)
12151229
{
12161230
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1230,6 +1244,13 @@ static int soc15_common_hw_init(void *handle)
12301244

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

12341255
return 0;
12351256
}

0 commit comments

Comments
 (0)