drm/rockchip: debugfs: add support write regs

We usually need to write vop regs for debug, but this depend on io cmd
and devm,
they are often forget to be enabled, so we add this node to instead of
it:

you can use the following cmd to update VOP regs:
  echo offset val > /sys/kernel/debug/dri/0/video_portx/regs_write

  the video_portx is depend on hardware config, you can get this info
from the cmd:
    cat /sys/kernel/debug/dri/0/summary

Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Change-Id: I687ecc44dc638bfdf770983f96ce7b5470ff3691
This commit is contained in:
Sandy Huang
2024-08-05 15:30:22 +08:00
committed by Tao Huang
parent 42188e945e
commit 20d88dd0fd
3 changed files with 75 additions and 0 deletions

View File

@@ -284,3 +284,70 @@ int rockchip_drm_debugfs_add_color_bar(struct drm_crtc *crtc, struct dentry *roo
return 0;
}
static int rockchip_drm_debugfs_regs_write_show(struct seq_file *s, void *data)
{
seq_puts(s, " Write VOP regs:\n");
seq_puts(s, " echo address val > /sys/kernel/debug/dri/0/video_portx/regs_write\n\n");
seq_puts(s, " video_portx is depend on hardware config, you can get this info from the cmd:\n");
seq_puts(s, " cat /sys/kernel/debug/dri/0/summary\n\n");
seq_puts(s, " Example:\n");
seq_puts(s, " echo 0x27d00000 0x1 > /sys/kernel/debug/dri/0/video_portx/regs_write\n\n");
return 0;
}
static int rockchip_drm_debugfs_regs_write_open(struct inode *inode, struct file *file)
{
struct drm_crtc *crtc = inode->i_private;
return single_open(file, rockchip_drm_debugfs_regs_write_show, crtc);
}
static ssize_t rockchip_drm_debugfs_regs_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp)
{
struct seq_file *s = file->private_data;
struct drm_crtc *crtc = s->private;
struct rockchip_drm_private *priv = crtc->dev->dev_private;
int ret = 0, pipe = drm_crtc_index(crtc);
unsigned long address = 0;
u32 val = 0;
char kbuf[32];
len = min_t(size_t, len, (sizeof(kbuf) - 1));
if (copy_from_user(kbuf, ubuf, len))
return -EINVAL;
kbuf[len] = 0;
if (sscanf(kbuf, "%lx %x", &address, &val) == -1)
return -EFAULT;
if (priv->crtc_funcs[pipe]->regs_write)
ret = priv->crtc_funcs[pipe]->regs_write(crtc, address, val);
if (ret)
return ret;
return len;
}
static const struct file_operations rockchip_drm_debugfs_regs_write_ops = {
.owner = THIS_MODULE,
.open = rockchip_drm_debugfs_regs_write_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = rockchip_drm_debugfs_regs_write,
};
int rockchip_drm_debugfs_add_regs_write(struct drm_crtc *crtc, struct dentry *root)
{
struct dentry *ent;
ent = debugfs_create_file("regs_write", 0644, root, crtc,
&rockchip_drm_debugfs_regs_write_ops);
if (!ent)
DRM_ERROR("Failed to add regs_write for debugfs\n");
return 0;
}

View File

@@ -36,6 +36,7 @@ rockchip_drm_crtc_dump_plane_buffer(struct drm_crtc *crtc)
}
#endif
int rockchip_drm_debugfs_add_color_bar(struct drm_crtc *crtc, struct dentry *root);
int rockchip_drm_debugfs_add_regs_write(struct drm_crtc *crtc, struct dentry *root);
#else
static inline int
rockchip_drm_add_dump_buffer(struct drm_crtc *crtc, struct dentry *root)
@@ -54,6 +55,12 @@ rockchip_drm_debugfs_add_color_bar(struct drm_crtc *crtc, struct dentry *root)
{
return 0;
}
static inline int
rockchip_drm_debugfs_add_regs_write(struct drm_crtc *crtc, struct dentry *root)
{
return 0;
}
#endif
#endif

View File

@@ -491,6 +491,7 @@ struct rockchip_crtc_funcs {
int (*debugfs_dump)(struct drm_crtc *crtc, struct seq_file *s);
void (*regs_dump)(struct drm_crtc *crtc, struct seq_file *s);
void (*active_regs_dump)(struct drm_crtc *crtc, struct seq_file *s);
int (*regs_write)(struct drm_crtc *crtc, phys_addr_t address, u32 val);
enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
int output_type);