From 2807aef659483de0d569b2c01e2b68be046496d3 Mon Sep 17 00:00:00 2001 From: Luke Diamand Date: Tue, 31 Dec 2013 23:07:36 +0000 Subject: [PATCH 148/174] bcm2708_fb: report number of dma copies Add a counter (exported via debugfs) reporting the number of dma copies that the framebuffer driver has done, in order to help evaluate different optimization strategies. Signed-off-by: Luke Diamand --- drivers/video/bcm2708_fb.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) --- a/drivers/video/bcm2708_fb.c +++ b/drivers/video/bcm2708_fb.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,12 @@ struct fbinfo_s { u16 cmap[256]; }; +struct bcm2708_fb_stats { + struct debugfs_regset32 regset; + u32 dma_copies; + u32 dma_irqs; +}; + struct bcm2708_fb { struct fb_info fb; struct platform_device *dev; @@ -69,10 +76,51 @@ struct bcm2708_fb { void __iomem *dma_chan_base; void *cb_base; /* DMA control blocks */ dma_addr_t cb_handle; + struct dentry *debugfs_dir; + struct bcm2708_fb_stats stats; }; #define to_bcm2708(info) container_of(info, struct bcm2708_fb, fb) +static void bcm2708_fb_debugfs_deinit(struct bcm2708_fb *fb) +{ + debugfs_remove_recursive(fb->debugfs_dir); + fb->debugfs_dir = NULL; +} + +static int bcm2708_fb_debugfs_init(struct bcm2708_fb *fb) +{ + static struct debugfs_reg32 stats_registers[] = { + { + "dma_copies", + offsetof(struct bcm2708_fb_stats, dma_copies) + }, + }; + + fb->debugfs_dir = debugfs_create_dir(DRIVER_NAME, NULL); + if (!fb->debugfs_dir) { + pr_warn("%s: could not create debugfs entry\n", + __func__); + return -EFAULT; + } + + fb->stats.regset.regs = stats_registers; + fb->stats.regset.nregs = ARRAY_SIZE(stats_registers); + fb->stats.regset.base = &fb->stats; + + if (!debugfs_create_regset32( + "stats", 0444, fb->debugfs_dir, &fb->stats.regset)) { + pr_warn("%s: could not create statistics registers\n", + __func__); + goto fail; + } + return 0; + +fail: + bcm2708_fb_debugfs_deinit(fb); + return -EFAULT; +} + static int bcm2708_fb_set_bitfields(struct fb_var_screeninfo *var) { int ret = 0; @@ -443,8 +491,10 @@ static void bcm2708_fb_copyarea(struct f /* end of dma control blocks chain */ cb->next = 0; + bcm_dma_start(fb->dma_chan_base, fb->cb_handle); bcm_dma_wait_idle(fb->dma_chan_base); + fb->stats.dma_copies++; } static void bcm2708_fb_imageblit(struct fb_info *info, @@ -552,6 +602,9 @@ static int bcm2708_fb_probe(struct platf } memset(fb, 0, sizeof(struct bcm2708_fb)); + + bcm2708_fb_debugfs_init(fb); + fb->cb_base = dma_alloc_writecombine(&dev->dev, SZ_64K, &fb->cb_handle, GFP_KERNEL); if (!fb->cb_base) { @@ -607,6 +660,8 @@ static int bcm2708_fb_remove(struct plat dma_free_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), (void *)fb->info, fb->dma); + bcm2708_fb_debugfs_deinit(fb); + kfree(fb); return 0;