This will be of great help when testing potential races between the GPU reset sequence and other parts of the code accessing HW registers.
Signed-off-by: Adrián Larumbe <[email protected]> --- drivers/gpu/drm/panfrost/panfrost_device.c | 41 ++++++++++++++++++++++++++++++ drivers/gpu/drm/panfrost/panfrost_device.h | 3 +++ drivers/gpu/drm/panfrost/panfrost_drv.c | 1 + 3 files changed, 45 insertions(+) diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c index a51f1ef8563c..c0334b72c70b 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.c +++ b/drivers/gpu/drm/panfrost/panfrost_device.c @@ -2,6 +2,7 @@ /* Copyright 2018 Marty E. Plummer <[email protected]> */ /* Copyright 2019 Linaro, Ltd, Rob Herring <[email protected]> */ +#include <linux/debugfs.h> #include <linux/clk.h> #include <linux/reset.h> #include <linux/platform_device.h> @@ -629,3 +630,43 @@ void panfrost_device_reset(struct panfrost_device *pfdev, bool enable_job_int) if (!panfrost_device_started(pfdev) && !ret) pfdev->gpu_started = true; } + +#ifdef CONFIG_DEBUG_FS +static int reset_get(void *data, u64 *val) +{ + struct panfrost_device *pfdev = + container_of(data, struct panfrost_device, base); + + *val = atomic_read(&pfdev->reset.pending); + return 0; +} + +static int reset_set(void *data, u64 val) +{ + struct panfrost_device *pfdev = + container_of(data, struct panfrost_device, base); + int ret; + + ret = pm_runtime_get_if_in_use(pfdev->base.dev); + + if (ret > 0) { + panfrost_device_schedule_reset(pfdev); + ret = wait_event_interruptible_timeout(pfdev->reset.wait, + !atomic_read(&pfdev->reset.pending), + msecs_to_jiffies(60)); + pm_runtime_put(pfdev->base.dev); + } + + return (ret > 0) ? 0 : -ETIMEDOUT; +} + +DEFINE_DEBUGFS_ATTRIBUTE(panfrost_reset_debugfs_fops, + reset_get, reset_set, + "0x%08llx\n"); + +void panfrost_reset_debugfs_init(struct drm_minor *minor) +{ + debugfs_create_file("reset", 0600, minor->debugfs_root, + minor->dev, &panfrost_reset_debugfs_fops); +} +#endif // CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h index f0acfc634cd4..f96ba50dfa91 100644 --- a/drivers/gpu/drm/panfrost/panfrost_device.h +++ b/drivers/gpu/drm/panfrost/panfrost_device.h @@ -352,4 +352,7 @@ panfrost_device_started(struct panfrost_device *pfdev) return pfdev->gpu_started; } +#ifdef CONFIG_DEBUG_FS +void panfrost_reset_debugfs_init(struct drm_minor *minor); +#endif // CONFIG_DEBUG_FS #endif diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 27f4c4b217f5..fac5be20ad60 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -916,6 +916,7 @@ static void panfrost_debugfs_init(struct drm_minor *minor) { panthor_gems_debugfs_init(minor); panfrost_sched_debugfs_init(minor); + panfrost_reset_debugfs_init(minor); } #endif -- 2.55.0
