From: Krzysztof H. <krz...@po...> - 2009-10-03 05:25:04
|
On Fri, 11 Sep 2009 20:05:02 +0200 Pawel Osciak <p.o...@sa...> wrote: > This patch adds debugfs information in s3c-fb directory in > debugfs root. > > Reviewed-by: Marek Szyprowski <m.s...@sa...> > Reviewed-by: Kyungmin Park <kyu...@sa...> > Signed-off-by: Pawel Osciak <p.o...@sa...> > > --- > 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) __devexit Regards, Krzysztof --------------------------------------------------------------- Przygotuj siê na przysz³o¶æ! Kliknij >>> http://link.interia.pl/f238a |