mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-07 15:07:13 -04:00
drm/xe/device: Use poll_timeout_us() to wait for lmem
Now that there's a generic poll_timeout_us(), use it to wait for LMEM_INIT in GU_CNTL. Reviewed-by: Maarten Lankhorst <dev@lankhorst.se> Link: https://lore.kernel.org/r/20250922-xe-iopoll-v4-1-06438311a63f@intel.com Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <linux/aperture.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fault-inject.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
@@ -630,16 +631,22 @@ static int xe_set_dma_info(struct xe_device *xe)
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool verify_lmem_ready(struct xe_device *xe)
|
||||
static int lmem_initializing(struct xe_device *xe)
|
||||
{
|
||||
u32 val = xe_mmio_read32(xe_root_tile_mmio(xe), GU_CNTL) & LMEM_INIT;
|
||||
if (xe_mmio_read32(xe_root_tile_mmio(xe), GU_CNTL) & LMEM_INIT)
|
||||
return 0;
|
||||
|
||||
return !!val;
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int wait_for_lmem_ready(struct xe_device *xe)
|
||||
{
|
||||
unsigned long timeout, start;
|
||||
const unsigned long TIMEOUT_SEC = 60;
|
||||
unsigned long prev_jiffies;
|
||||
int initializing;
|
||||
|
||||
if (!IS_DGFX(xe))
|
||||
return 0;
|
||||
@@ -647,39 +654,35 @@ static int wait_for_lmem_ready(struct xe_device *xe)
|
||||
if (IS_SRIOV_VF(xe))
|
||||
return 0;
|
||||
|
||||
if (verify_lmem_ready(xe))
|
||||
if (!lmem_initializing(xe))
|
||||
return 0;
|
||||
|
||||
drm_dbg(&xe->drm, "Waiting for lmem initialization\n");
|
||||
prev_jiffies = jiffies;
|
||||
|
||||
start = jiffies;
|
||||
timeout = start + secs_to_jiffies(60); /* 60 sec! */
|
||||
/*
|
||||
* The boot firmware initializes local memory and
|
||||
* assesses its health. If memory training fails,
|
||||
* the punit will have been instructed to keep the GT powered
|
||||
* down.we won't be able to communicate with it
|
||||
*
|
||||
* If the status check is done before punit updates the register,
|
||||
* it can lead to the system being unusable.
|
||||
* use a timeout and defer the probe to prevent this.
|
||||
*/
|
||||
poll_timeout_us(initializing = lmem_initializing(xe),
|
||||
initializing <= 0,
|
||||
20 * USEC_PER_MSEC, TIMEOUT_SEC * USEC_PER_SEC, true);
|
||||
if (initializing < 0)
|
||||
return initializing;
|
||||
|
||||
do {
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
|
||||
/*
|
||||
* The boot firmware initializes local memory and
|
||||
* assesses its health. If memory training fails,
|
||||
* the punit will have been instructed to keep the GT powered
|
||||
* down.we won't be able to communicate with it
|
||||
*
|
||||
* If the status check is done before punit updates the register,
|
||||
* it can lead to the system being unusable.
|
||||
* use a timeout and defer the probe to prevent this.
|
||||
*/
|
||||
if (time_after(jiffies, timeout)) {
|
||||
drm_dbg(&xe->drm, "lmem not initialized by firmware\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
msleep(20);
|
||||
|
||||
} while (!verify_lmem_ready(xe));
|
||||
if (initializing) {
|
||||
drm_dbg(&xe->drm, "lmem not initialized by firmware\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
drm_dbg(&xe->drm, "lmem ready after %ums",
|
||||
jiffies_to_msecs(jiffies - start));
|
||||
jiffies_to_msecs(jiffies - prev_jiffies));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user