mirror of
https://github.com/torvalds/linux
synced 2024-09-06 18:01:05 +00:00
drm/panfrost: Replace fdinfo's profiling debugfs knob with sysfs
Debugfs isn't always available in production builds that try to squeeze every single byte out of the kernel image, but we still need a way to toggle the timestamp and cycle counter registers so that jobs can be profiled for fdinfo's drm engine and cycle calculations. Drop the debugfs knob and replace it with a sysfs file that accomplishes the same functionality, and document its ABI in a separate file. Signed-off-by: Adrián Larumbe <adrian.larumbe@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240306015819.822128-2-adrian.larumbe@collabora.com
This commit is contained in:
parent
57a4e3a94c
commit
b12f3ea7c1
10
Documentation/ABI/testing/sysfs-driver-panfrost-profiling
Normal file
10
Documentation/ABI/testing/sysfs-driver-panfrost-profiling
Normal file
|
@ -0,0 +1,10 @@
|
|||
What: /sys/bus/platform/drivers/panfrost/.../profiling
|
||||
Date: February 2024
|
||||
KernelVersion: 6.8.0
|
||||
Contact: Adrian Larumbe <adrian.larumbe@collabora.com>
|
||||
Description:
|
||||
Get/set drm fdinfo's engine and cycles profiling status.
|
||||
Valid values are:
|
||||
0: Don't enable fdinfo job profiling sources.
|
||||
1: Enable fdinfo job profiling sources, this enables both the GPU's
|
||||
timestamp and cycle counter registers.
|
|
@ -38,3 +38,12 @@ the currently possible format options:
|
|||
|
||||
Possible `drm-engine-` key names are: `fragment`, and `vertex-tiler`.
|
||||
`drm-curfreq-` values convey the current operating frequency for that engine.
|
||||
|
||||
Users must bear in mind that engine and cycle sampling are disabled by default,
|
||||
because of power saving concerns. `fdinfo` users and benchmark applications which
|
||||
query the fdinfo file must make sure to toggle the job profiling status of the
|
||||
driver by writing into the appropriate sysfs node::
|
||||
|
||||
echo <N> > /sys/bus/platform/drivers/panfrost/[a-f0-9]*.gpu/profiling
|
||||
|
||||
Where `N` is either `0` or `1`, depending on the desired enablement status.
|
||||
|
|
|
@ -12,6 +12,4 @@ panfrost-y := \
|
|||
panfrost_perfcnt.o \
|
||||
panfrost_dump.o
|
||||
|
||||
panfrost-$(CONFIG_DEBUG_FS) += panfrost_debugfs.o
|
||||
|
||||
obj-$(CONFIG_DRM_PANFROST) += panfrost.o
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright 2023 Collabora ltd. */
|
||||
/* Copyright 2023 Amazon.com, Inc. or its affiliates. */
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <drm/drm_debugfs.h>
|
||||
#include <drm/drm_file.h>
|
||||
#include <drm/panfrost_drm.h>
|
||||
|
||||
#include "panfrost_device.h"
|
||||
#include "panfrost_gpu.h"
|
||||
#include "panfrost_debugfs.h"
|
||||
|
||||
void panfrost_debugfs_init(struct drm_minor *minor)
|
||||
{
|
||||
struct drm_device *dev = minor->dev;
|
||||
struct panfrost_device *pfdev = platform_get_drvdata(to_platform_device(dev->dev));
|
||||
|
||||
debugfs_create_atomic_t("profile", 0600, minor->debugfs_root, &pfdev->profile_mode);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright 2023 Collabora ltd.
|
||||
* Copyright 2023 Amazon.com, Inc. or its affiliates.
|
||||
*/
|
||||
|
||||
#ifndef PANFROST_DEBUGFS_H
|
||||
#define PANFROST_DEBUGFS_H
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void panfrost_debugfs_init(struct drm_minor *minor);
|
||||
#endif
|
||||
|
||||
#endif /* PANFROST_DEBUGFS_H */
|
|
@ -130,7 +130,7 @@ struct panfrost_device {
|
|||
struct list_head scheduled_jobs;
|
||||
|
||||
struct panfrost_perfcnt *perfcnt;
|
||||
atomic_t profile_mode;
|
||||
bool profile_mode;
|
||||
|
||||
struct mutex sched_lock;
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "panfrost_job.h"
|
||||
#include "panfrost_gpu.h"
|
||||
#include "panfrost_perfcnt.h"
|
||||
#include "panfrost_debugfs.h"
|
||||
|
||||
static bool unstable_ioctls;
|
||||
module_param_unsafe(unstable_ioctls, bool, 0600);
|
||||
|
@ -600,10 +599,6 @@ static const struct drm_driver panfrost_drm_driver = {
|
|||
|
||||
.gem_create_object = panfrost_gem_create_object,
|
||||
.gem_prime_import_sg_table = panfrost_gem_prime_import_sg_table,
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
.debugfs_init = panfrost_debugfs_init,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int panfrost_probe(struct platform_device *pdev)
|
||||
|
@ -692,6 +687,40 @@ static void panfrost_remove(struct platform_device *pdev)
|
|||
drm_dev_put(ddev);
|
||||
}
|
||||
|
||||
static ssize_t profiling_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct panfrost_device *pfdev = dev_get_drvdata(dev);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", pfdev->profile_mode);
|
||||
}
|
||||
|
||||
static ssize_t profiling_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct panfrost_device *pfdev = dev_get_drvdata(dev);
|
||||
bool value;
|
||||
int err;
|
||||
|
||||
err = kstrtobool(buf, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pfdev->profile_mode = value;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(profiling);
|
||||
|
||||
static struct attribute *panfrost_attrs[] = {
|
||||
&dev_attr_profiling.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
ATTRIBUTE_GROUPS(panfrost);
|
||||
|
||||
/*
|
||||
* The OPP core wants the supply names to be NULL terminated, but we need the
|
||||
* correct num_supplies value for regulator core. Hence, we NULL terminate here
|
||||
|
@ -789,6 +818,7 @@ static struct platform_driver panfrost_driver = {
|
|||
.name = "panfrost",
|
||||
.pm = pm_ptr(&panfrost_pm_ops),
|
||||
.of_match_table = dt_match,
|
||||
.dev_groups = panfrost_groups,
|
||||
},
|
||||
};
|
||||
module_platform_driver(panfrost_driver);
|
||||
|
|
|
@ -243,7 +243,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js)
|
|||
subslot = panfrost_enqueue_job(pfdev, js, job);
|
||||
/* Don't queue the job if a reset is in progress */
|
||||
if (!atomic_read(&pfdev->reset.pending)) {
|
||||
if (atomic_read(&pfdev->profile_mode)) {
|
||||
if (pfdev->profile_mode) {
|
||||
panfrost_cycle_counter_get(pfdev);
|
||||
job->is_profiled = true;
|
||||
job->start_time = ktime_get();
|
||||
|
|
Loading…
Reference in a new issue