113 lines
2.6 KiB
C
113 lines
2.6 KiB
C
|
// SPDX-License-Identifier: GPL-2.0+
|
||
|
/*
|
||
|
* Debugfs tracing for bitstream buffers. This is similar to VA-API's
|
||
|
* LIBVA_TRACE_BUFDATA in that the raw bitstream can be dumped as a debugging
|
||
|
* aid.
|
||
|
*
|
||
|
* Produces one file per OUTPUT buffer. Files are automatically cleared on
|
||
|
* STREAMOFF unless the module parameter "keep_bitstream_buffers" is set.
|
||
|
*/
|
||
|
|
||
|
#include <linux/debugfs.h>
|
||
|
#include <linux/list.h>
|
||
|
#include <linux/mutex.h>
|
||
|
#include <media/v4l2-mem2mem.h>
|
||
|
|
||
|
#include "visl-debugfs.h"
|
||
|
|
||
|
int visl_debugfs_init(struct visl_dev *dev)
|
||
|
{
|
||
|
dev->debugfs_root = debugfs_create_dir("visl", NULL);
|
||
|
INIT_LIST_HEAD(&dev->bitstream_blobs);
|
||
|
mutex_init(&dev->bitstream_lock);
|
||
|
|
||
|
if (IS_ERR(dev->debugfs_root))
|
||
|
return PTR_ERR(dev->debugfs_root);
|
||
|
|
||
|
return visl_debugfs_bitstream_init(dev);
|
||
|
}
|
||
|
|
||
|
int visl_debugfs_bitstream_init(struct visl_dev *dev)
|
||
|
{
|
||
|
dev->bitstream_debugfs = debugfs_create_dir("bitstream",
|
||
|
dev->debugfs_root);
|
||
|
if (IS_ERR(dev->bitstream_debugfs))
|
||
|
return PTR_ERR(dev->bitstream_debugfs);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void visl_trace_bitstream(struct visl_ctx *ctx, struct visl_run *run)
|
||
|
{
|
||
|
u8 *vaddr = vb2_plane_vaddr(&run->src->vb2_buf, 0);
|
||
|
struct visl_blob *blob;
|
||
|
size_t data_sz = vb2_get_plane_payload(&run->src->vb2_buf, 0);
|
||
|
struct dentry *dentry;
|
||
|
char name[32];
|
||
|
|
||
|
blob = kzalloc(sizeof(*blob), GFP_KERNEL);
|
||
|
if (!blob)
|
||
|
return;
|
||
|
|
||
|
blob->blob.data = vzalloc(data_sz);
|
||
|
if (!blob->blob.data)
|
||
|
goto err_vmalloc;
|
||
|
|
||
|
blob->blob.size = data_sz;
|
||
|
snprintf(name, 32, "bitstream%d", run->src->sequence);
|
||
|
|
||
|
memcpy(blob->blob.data, vaddr, data_sz);
|
||
|
|
||
|
dentry = debugfs_create_blob(name, 0444, ctx->dev->bitstream_debugfs,
|
||
|
&blob->blob);
|
||
|
if (IS_ERR(dentry))
|
||
|
goto err_debugfs;
|
||
|
|
||
|
blob->dentry = dentry;
|
||
|
|
||
|
mutex_lock(&ctx->dev->bitstream_lock);
|
||
|
list_add_tail(&blob->list, &ctx->dev->bitstream_blobs);
|
||
|
mutex_unlock(&ctx->dev->bitstream_lock);
|
||
|
|
||
|
return;
|
||
|
|
||
|
err_debugfs:
|
||
|
vfree(blob->blob.data);
|
||
|
err_vmalloc:
|
||
|
kfree(blob);
|
||
|
}
|
||
|
|
||
|
void visl_debugfs_clear_bitstream(struct visl_dev *dev)
|
||
|
{
|
||
|
struct visl_blob *blob;
|
||
|
struct visl_blob *tmp;
|
||
|
|
||
|
mutex_lock(&dev->bitstream_lock);
|
||
|
if (list_empty(&dev->bitstream_blobs))
|
||
|
goto unlock;
|
||
|
|
||
|
list_for_each_entry_safe(blob, tmp, &dev->bitstream_blobs, list) {
|
||
|
list_del(&blob->list);
|
||
|
debugfs_remove(blob->dentry);
|
||
|
vfree(blob->blob.data);
|
||
|
kfree(blob);
|
||
|
}
|
||
|
|
||
|
unlock:
|
||
|
mutex_unlock(&dev->bitstream_lock);
|
||
|
}
|
||
|
|
||
|
void visl_debugfs_bitstream_deinit(struct visl_dev *dev)
|
||
|
{
|
||
|
visl_debugfs_clear_bitstream(dev);
|
||
|
debugfs_remove_recursive(dev->bitstream_debugfs);
|
||
|
dev->bitstream_debugfs = NULL;
|
||
|
}
|
||
|
|
||
|
void visl_debugfs_deinit(struct visl_dev *dev)
|
||
|
{
|
||
|
visl_debugfs_bitstream_deinit(dev);
|
||
|
debugfs_remove_recursive(dev->debugfs_root);
|
||
|
dev->debugfs_root = NULL;
|
||
|
}
|