Skip to content

Commit 3938eb9

Browse files
committed
drm/amdgpu: add a retry for IP discovery init
AMD dGPUs have integrated FW that runs as soon as the device gets power and initializes the board (determines the amount of memory, provides configuration details to the driver, etc.). For direct PCIe attached cards this happens as soon as power is applied and normally completes well before the OS has even started loading. However, with hotpluggable ports like USB4, the driver needs to wait for this to complete before initializing the device. This normally takes 60-100ms, but could take longer on some older boards periodically due to memory training. Retry for up to a second. In the non-hotplug case, there should be no change in behavior and this should complete on the first try. v2: adjust test criteria v3: adjust checks for the masks, only enable on removable devices v4: skip bif_fb_en check Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2925 Reviewed-by: Mario Limonciello <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Cc: [email protected]
1 parent 886b92f commit 3938eb9

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
MODULE_FIRMWARE(FIRMWARE_IP_DISCOVERY);
100100

101101
#define mmRCC_CONFIG_MEMSIZE 0xde3
102+
#define mmMP0_SMN_C2PMSG_33 0x16061
102103
#define mmMM_INDEX 0x0
103104
#define mmMM_INDEX_HI 0x6
104105
#define mmMM_DATA 0x1
@@ -239,8 +240,26 @@ static int amdgpu_discovery_read_binary_from_sysmem(struct amdgpu_device *adev,
239240
static int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev,
240241
uint8_t *binary)
241242
{
242-
uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
243-
int ret = 0;
243+
uint64_t vram_size;
244+
u32 msg;
245+
int i, ret = 0;
246+
247+
/* It can take up to a second for IFWI init to complete on some dGPUs,
248+
* but generally it should be in the 60-100ms range. Normally this starts
249+
* as soon as the device gets power so by the time the OS loads this has long
250+
* completed. However, when a card is hotplugged via e.g., USB4, we need to
251+
* wait for this to complete. Once the C2PMSG is updated, we can
252+
* continue.
253+
*/
254+
if (dev_is_removable(&adev->pdev->dev)) {
255+
for (i = 0; i < 1000; i++) {
256+
msg = RREG32(mmMP0_SMN_C2PMSG_33);
257+
if (msg & 0x80000000)
258+
break;
259+
msleep(1);
260+
}
261+
}
262+
vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20;
244263

245264
if (vram_size) {
246265
uint64_t pos = vram_size - DISCOVERY_TMR_OFFSET;

0 commit comments

Comments
 (0)