summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-3.10/0148-bcm2708_fb-report-number-of-dma-copies.patch
blob: cd09a729b2f5e37f45d9e60559d7ade424eee226 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
From 2807aef659483de0d569b2c01e2b68be046496d3 Mon Sep 17 00:00:00 2001
From: Luke Diamand <luked@broadcom.com>
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 <luked@broadcom.com>
---
 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 <linux/clk.h>
 #include <linux/printk.h>
 #include <linux/console.h>
+#include <linux/debugfs.h>
 
 #include <mach/dma.h>
 #include <mach/platform.h>
@@ -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;