From 20d88dd0fdfa9907873cd184b8c2c3633df2694a Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Mon, 5 Aug 2024 15:30:22 +0800 Subject: [PATCH] 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 Change-Id: I687ecc44dc638bfdf770983f96ce7b5470ff3691 --- .../gpu/drm/rockchip/rockchip_drm_debugfs.c | 67 +++++++++++++++++++ .../gpu/drm/rockchip/rockchip_drm_debugfs.h | 7 ++ drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 + 3 files changed, 75 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c b/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c index 456d82d884ad..8d71df1d4cbf 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.c @@ -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; +} diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.h b/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.h index 6e63da0a188c..2f8ec1677245 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_debugfs.h @@ -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 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index 42e194b24574..b65781c36f96 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -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);