mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
Add support for allocating buffers from reserved carveout memory when IOMMU is not available. This is useful during debugging or bring-up. In this configuration, the device uses physical addresses and does not support scatter-gather lists, requiring physically contiguous buffers. Implement carveout-backed allocation and integrate it into buffer management to support operation in physical address mode. Signed-off-by: Max Zhen <max.zhen@amd.com> Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org> Signed-off-by: Lizhi Hou <lizhi.hou@amd.com> Link: https://patch.msgid.link/20260427170949.2666601-1-lizhi.hou@amd.com
130 lines
3.0 KiB
C
130 lines
3.0 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2026, Advanced Micro Devices, Inc.
|
|
*/
|
|
|
|
#include "amdxdna_cbuf.h"
|
|
#include "amdxdna_debugfs.h"
|
|
|
|
#include <drm/drm_file.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/string.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
#define _DBGFS_FOPS(_open, _release, _write) \
|
|
{ \
|
|
.owner = THIS_MODULE, \
|
|
.open = _open, \
|
|
.read = seq_read, \
|
|
.llseek = seq_lseek, \
|
|
.release = _release, \
|
|
.write = _write, \
|
|
}
|
|
|
|
#define AMDXDNA_DBGFS_FOPS(_name, _show, _write) \
|
|
static int amdxdna_dbgfs_##_name##_open(struct inode *inode, struct file *file) \
|
|
{ \
|
|
return single_open(file, _show, inode->i_private); \
|
|
} \
|
|
static int amdxdna_dbgfs_##_name##_release(struct inode *inode, struct file *file) \
|
|
{ \
|
|
return single_release(inode, file); \
|
|
} \
|
|
static const struct file_operations amdxdna_fops_##_name = \
|
|
_DBGFS_FOPS(amdxdna_dbgfs_##_name##_open, amdxdna_dbgfs_##_name##_release, _write)
|
|
|
|
#define AMDXDNA_DBGFS_FILE(_name, _mode) { #_name, &amdxdna_fops_##_name, _mode }
|
|
|
|
#define file_to_xdna(file) (((struct seq_file *)(file)->private_data)->private)
|
|
|
|
static ssize_t amdxdna_carveout_write(struct file *file, const char __user *buf,
|
|
size_t count, loff_t *ppos)
|
|
{
|
|
struct amdxdna_dev *xdna = file_to_xdna(file);
|
|
char kbuf[128];
|
|
u64 size, addr;
|
|
char *sep;
|
|
int ret;
|
|
|
|
if (count == 0 || count >= sizeof(kbuf))
|
|
return -EINVAL;
|
|
|
|
if (copy_from_user(kbuf, buf, count))
|
|
return -EFAULT;
|
|
kbuf[count] = '\0';
|
|
strim(kbuf);
|
|
XDNA_DBG(xdna, "Trying to set carveout to %s", kbuf);
|
|
|
|
sep = strchr(kbuf, '@');
|
|
if (!sep)
|
|
return -EINVAL;
|
|
*sep = '\0';
|
|
sep++;
|
|
|
|
ret = kstrtou64(kbuf, 0, &size);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = kstrtou64(sep, 0, &addr);
|
|
if (ret)
|
|
return ret;
|
|
|
|
/* Sanity check the addr and size. */
|
|
if (!size)
|
|
return -EINVAL;
|
|
if (!IS_ALIGNED(addr, PAGE_SIZE) || !IS_ALIGNED(size, PAGE_SIZE))
|
|
return -EINVAL;
|
|
|
|
guard(mutex)(&xdna->dev_lock);
|
|
|
|
ret = amdxdna_carveout_init(xdna, addr, size);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return count;
|
|
}
|
|
|
|
static int amdxdna_carveout_show(struct seq_file *m, void *unused)
|
|
{
|
|
struct amdxdna_dev *xdna = m->private;
|
|
u64 addr, size;
|
|
|
|
guard(mutex)(&xdna->dev_lock);
|
|
amdxdna_get_carveout_conf(xdna, &addr, &size);
|
|
seq_printf(m, "0x%llx@0x%llx\n", size, addr);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Input/output format: <carveout_size>@<carveout_address>
|
|
*/
|
|
AMDXDNA_DBGFS_FOPS(carveout, amdxdna_carveout_show, amdxdna_carveout_write);
|
|
|
|
static const struct {
|
|
const char *name;
|
|
const struct file_operations *fops;
|
|
umode_t mode;
|
|
} amdxdna_dbgfs_files[] = {
|
|
AMDXDNA_DBGFS_FILE(carveout, 0600),
|
|
};
|
|
|
|
void amdxdna_debugfs_init(struct amdxdna_dev *xdna)
|
|
{
|
|
struct drm_minor *minor = xdna->ddev.accel;
|
|
int i;
|
|
|
|
/*
|
|
* It should be okay that debugfs fails to init.
|
|
* We rely on DRM framework to finish debugfs.
|
|
*/
|
|
for (i = 0; i < ARRAY_SIZE(amdxdna_dbgfs_files); i++) {
|
|
debugfs_create_file(amdxdna_dbgfs_files[i].name,
|
|
amdxdna_dbgfs_files[i].mode,
|
|
minor->debugfs_root,
|
|
xdna,
|
|
amdxdna_dbgfs_files[i].fops);
|
|
}
|
|
}
|