[PATCH 6/7] [ARM] s3c-fb: Added debugfs interface.
Pawel Osciak
p.osciak at samsung.com
Fri Sep 11 14:05:02 EDT 2009
This patch adds debugfs information in s3c-fb directory in
debugfs root.
Reviewed-by: Marek Szyprowski <m.szyprowski at samsung.com>
Reviewed-by: Kyungmin Park <kyungmin.park at samsung.com>
Signed-off-by: Pawel Osciak <p.osciak at samsung.com>
---
drivers/video/Kconfig | 16 +++-
drivers/video/s3c-fb.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 249 insertions(+), 4 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3b54b39..922a1cb 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1917,10 +1917,18 @@ config FB_S3C
Currently the support is only for the S3C6400 and S3C6410 SoCs.
config FB_S3C_DEBUG_REGWRITE
- bool "Debug register writes"
- depends on FB_S3C
- ---help---
- Show all register writes via printk(KERN_DEBUG)
+ bool "Debug register writes"
+ depends on FB_S3C
+ ---help---
+ Show all register writes via printk(KERN_DEBUG)
+
+config FB_S3C_DEBUG_FS
+ bool "Enable debug information in DebugFS"
+ depends on FB_S3C && DEBUG_FS
+ default n
+ ---help---
+ Enable this if you want debugging information in debugfs.
+ If unsure, say N.
config FB_S3C2410
tristate "S3C2410 LCD framebuffer support"
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 226d225..6721f20 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -26,6 +26,12 @@
#include <plat/s3c-fb.h>
+#ifdef CONFIG_FB_S3C_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#endif
+
+
#include <mach/map.h>
#include <mach/regs-fb.h>
#include <plat/fb.h>
@@ -62,6 +68,11 @@
struct s3c_fb;
+#ifdef CONFIG_FB_S3C_DEBUG_FS
+static void __devinit s3c_fb_debugfs_init(struct s3c_fb *sfb);
+static void __devinit s3c_fb_debugfs_remove(void);
+#endif
+
/**
* struct s3c_fb_win - per window private data for each framebuffer.
* @windata: The platform data supplied for the window configuration.
@@ -1441,6 +1452,10 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sfb);
+#ifdef CONFIG_FB_S3C_DEBUG_FS
+ s3c_fb_debugfs_init(sfb);
+#endif
+
return 0;
err_irq:
@@ -1474,6 +1489,10 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
struct s3c_fb *sfb = platform_get_drvdata(pdev);
int win;
+#ifdef CONFIG_FB_S3C_DEBUG_FS
+ s3c_fb_debugfs_remove();
+#endif
+
for (win = 0; win < S3C_FB_MAX_WIN; win++)
if (sfb->windows[win])
s3c_fb_release_win(sfb, sfb->windows[win]);
@@ -1567,6 +1586,224 @@ static void __exit s3c_fb_cleanup(void)
platform_driver_unregister(&s3c_fb_driver);
}
+/* DEBUGFS */
+
+#ifdef CONFIG_FB_S3C_DEBUG_FS
+static struct dentry *debugfs_dir;
+
+static void *dbg_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ int *win_no;
+
+ if (v == SEQ_START_TOKEN)
+ return pos;
+
+ win_no = (int *)pos;
+ *win_no += 1;
+ if (*win_no >= S3C_FB_MAX_WIN)
+ return NULL;
+
+ return pos;
+}
+
+static int dbg_blend_seq_show(struct seq_file *s, void *v)
+{
+ struct s3c_fb *sfb = s->private;
+ int *win_no = v;
+ u32 vidosdc, wincon;
+
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(s, "win| mode AEN0 AEN1\n");
+ return 0;
+ }
+
+ if (!s3c_fb_has_alpha(*win_no))
+ return SEQ_SKIP;
+
+ seq_printf(s, "%2d | ", *win_no);
+
+ vidosdc = readl(sfb->regs + VIDOSD_C(*win_no));
+ wincon = readl(sfb->regs + WINCONx(*win_no));
+ if (wincon & WINCONx_BLD_PIX) {
+ seq_printf(s, " per pixel ");
+ if (wincon & WINCONx_ALPHA_SEL)
+ seq_printf(s, "value ");
+ else
+ seq_printf(s, "global ");
+ } else {
+ seq_printf(s, " global ");
+ if (wincon & WINCONx_ALPHA_SEL)
+ seq_printf(s, "val 1 ");
+ else
+ seq_printf(s, "val 0 ");
+ }
+ seq_printf(s, "%04x %04x\n",
+ (vidosdc & VIDOSD14C_ALPHA0_MASK)
+ >> VIDOSD14C_ALPHA0_B_SHIFT,
+ vidosdc & VIDOSD14C_ALPHA1_MASK);
+
+ return 0;
+}
+
+static int dbg_ckey_seq_show(struct seq_file *s, void *v)
+{
+ struct s3c_fb *sfb = s->private;
+ int *win_no = v;
+ u32 keycon0, keycon1;
+
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(s, "win| enabled direction value mask\n");
+ return 0;
+ }
+
+ if (!has_colorkey(*win_no))
+ return SEQ_SKIP;
+
+ seq_printf(s, "%2d | ", *win_no);
+
+ keycon0 = readl(sfb->regs + WxKEYCON0(*win_no));
+ keycon1 = readl(sfb->regs + WxKEYCON1(*win_no));
+
+ seq_printf(s, " %d ", keycon0 & WxKEYCON0_KEYEN_F);
+ if (keycon0 & WxKEYCON0_DIRCON)
+ seq_printf(s, " FG ");
+ else
+ seq_printf(s, " BG ");
+
+ seq_printf(s, " %06x ", keycon1 & WxKEYCON1_COLVAL_MASK);
+ seq_printf(s, "%06x ", keycon0 & WxKEYCON0_COMPKEY_MASK);
+ seq_printf(s, "\n");
+
+ return 0;
+}
+
+static inline void *single_start(struct seq_file *p, loff_t *pos)
+{
+ if (*pos == 0)
+ return SEQ_START_TOKEN;
+
+ return NULL + (*pos == 0);
+}
+
+static inline void single_stop(struct seq_file *p, void *v)
+{
+}
+
+static const struct seq_operations dbg_blend_seq_ops = {
+ .start = single_start,
+ .next = dbg_seq_next,
+ .stop = single_stop,
+ .show = dbg_blend_seq_show,
+};
+
+static const struct seq_operations dbg_ckey_seq_ops = {
+ .start = single_start,
+ .next = dbg_seq_next,
+ .stop = single_stop,
+ .show = dbg_ckey_seq_show,
+};
+
+static int dbg_blend_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int ret;
+
+ ret = seq_open(file, &dbg_blend_seq_ops);
+ if (ret)
+ return ret;
+
+ seq = file->private_data;
+ seq->private = inode->i_private;
+
+ return 0;
+}
+
+static const struct file_operations dbg_blend_fops = {
+ .owner = THIS_MODULE,
+ .open = dbg_blend_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int dbg_ckey_open(struct inode *inode, struct file *file)
+{
+ struct seq_file *seq;
+ int ret;
+
+ ret = seq_open(file, &dbg_ckey_seq_ops);
+ if (ret)
+ return ret;
+
+ seq = file->private_data;
+ seq->private = inode->i_private;
+
+ return 0;
+}
+
+static const struct file_operations dbg_ckey_fops = {
+ .owner = THIS_MODULE,
+ .open = dbg_ckey_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int dbg_winen_show(struct seq_file *s, void *v)
+{
+ struct s3c_fb *sfb = s->private;
+ int win_no;
+
+ for (win_no = 0; win_no < S3C_FB_MAX_WIN; ++win_no) {
+ if (sfb->enabled & (1 << win_no))
+ seq_printf(s, "Win%d: enabled\n", win_no);
+ else
+ seq_printf(s, "Win%d: disabled\n", win_no);
+ }
+
+ return 0;
+}
+
+static int dbg_winen_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_winen_show, inode->i_private);
+}
+
+static const struct file_operations dbg_winen_fops = {
+ .owner = THIS_MODULE,
+ .open = dbg_winen_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void __devinit s3c_fb_debugfs_init(struct s3c_fb *sfb)
+{
+ debugfs_dir = debugfs_create_dir("s3c-fb", NULL);
+ if (! debugfs_dir || IS_ERR(debugfs_dir)) {
+ dev_warn(sfb->dev, "Could not create debugfs directory\n");
+ return;
+ }
+
+ debugfs_create_file("windows_enabled", S_IRUGO, debugfs_dir, sfb,
+ &dbg_winen_fops);
+
+ debugfs_create_file("blending", S_IRUGO, debugfs_dir, sfb,
+ &dbg_blend_fops);
+
+ debugfs_create_file("color_key", S_IRUGO, debugfs_dir, sfb,
+ &dbg_ckey_fops);
+}
+
+static void __devinit s3c_fb_debugfs_remove(void)
+{
+ if (debugfs_dir)
+ debugfs_remove_recursive(debugfs_dir);
+}
+#endif /* CONFIG_DEBUG_FS */
+
+/* DEBUGFS END */
+
module_init(s3c_fb_init);
module_exit(s3c_fb_cleanup);
--
1.6.4.2.253.g0b1fac
More information about the linux-arm-kernel
mailing list