aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <molnar@ti.com>2011-07-13 22:13:54 -0400
committerPaolo Pisati <paolo.pisati@canonical.com>2012-08-17 04:19:06 -0400
commit0200964daf35597a1b44165eb3ff4236e75ee318 (patch)
tree8e3b4f8afdcafee0021f4b99224ae493d7b5417b
parent9eae825bfa7dcc2f6015b6d091c254e36f280244 (diff)
OMAP:TILER: Add debugfs interfaces for Tiler
Added <debugfs>/tiler/map/2x1 file which contains the TILER container map subsampled 2x1. Reading this file will perform a dump of the tiler container. Added <debugfs/tiler/alloc_debug debugfs parameter. Setting this parameter to a non-zero value will cause debug prints for each area allocation and deallocation. Signed-off-by: Lajos Molnar <molnar@ti.com> Signed-off-by: Andy Gross<andy.gross@ti.com>
-rw-r--r--drivers/media/video/tiler/tiler-main.c218
1 files changed, 217 insertions, 1 deletions
diff --git a/drivers/media/video/tiler/tiler-main.c b/drivers/media/video/tiler/tiler-main.c
index 92aac12dc3a..5feb83507a2 100644
--- a/drivers/media/video/tiler/tiler-main.c
+++ b/drivers/media/video/tiler/tiler-main.c
@@ -31,6 +31,8 @@
31#include <linux/pagemap.h> /* page_cache_release() */ 31#include <linux/pagemap.h> /* page_cache_release() */
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/debugfs.h>
35#include <linux/seq_file.h>
34 36
35#include <mach/dmm.h> 37#include <mach/dmm.h>
36#include "tmm.h" 38#include "tmm.h"
@@ -40,6 +42,7 @@
40static bool ssptr_id = CONFIG_TILER_SSPTR_ID; 42static bool ssptr_id = CONFIG_TILER_SSPTR_ID;
41static uint default_align = CONFIG_TILER_ALIGNMENT; 43static uint default_align = CONFIG_TILER_ALIGNMENT;
42static uint granularity = CONFIG_TILER_GRANULARITY; 44static uint granularity = CONFIG_TILER_GRANULARITY;
45static u32 tiler_alloc_debug;
43 46
44/* 47/*
45 * We can only change ssptr_id if there are no blocks allocated, so that 48 * We can only change ssptr_id if there are no blocks allocated, so that
@@ -52,10 +55,14 @@ module_param_named(align, default_align, uint, 0644);
52MODULE_PARM_DESC(align, "Default block ssptr alignment"); 55MODULE_PARM_DESC(align, "Default block ssptr alignment");
53module_param_named(grain, granularity, uint, 0644); 56module_param_named(grain, granularity, uint, 0644);
54MODULE_PARM_DESC(grain, "Granularity (bytes)"); 57MODULE_PARM_DESC(grain, "Granularity (bytes)");
58module_param_named(alloc_debug, tiler_alloc_debug, uint, 0644);
59MODULE_PARM_DESC(alloc_debug, "Allocation debug flag");
55 60
56struct tiler_dev { 61struct tiler_dev {
57 struct cdev cdev; 62 struct cdev cdev;
58}; 63};
64static struct dentry *dbgfs;
65static struct dentry *dbg_map;
59 66
60struct platform_driver tiler_driver_ldm = { 67struct platform_driver tiler_driver_ldm = {
61 .driver = { 68 .driver = {
@@ -163,6 +170,152 @@ static u32 _m_get_id(void)
163 return id; 170 return id;
164} 171}
165 172
173#define TILER_WIDTH 256
174#define TILER_HEIGHT 128
175
176static void fill_map(char **map, int div, struct tcm_area *a, char c, bool ovw)
177{
178 int x, y;
179 for (y = a->p0.y; y <= a->p1.y; y++)
180 for (x = a->p0.x / div; x <= a->p1.x / div; x++)
181 if (map[y][x] == ' ' || ovw)
182 map[y][x] = c;
183}
184
185static void fill_map_pt(char **map, int div, struct tcm_pt *p, char c)
186{
187 map[p->y][p->x / div] = c;
188}
189
190static char read_map_pt(char **map, int div, struct tcm_pt *p)
191{
192 return map[p->y][p->x / div];
193}
194
195static int map_width(int div, int x0, int x1)
196{
197 return (x1 / div) - (x0 / div) + 1;
198}
199
200static void text_map(char **map, int div, char *nice, int y, int x0, int x1)
201{
202 char *p = map[y] + (x0 / div);
203 int w = (map_width(div, x0, x1) - strlen(nice)) / 2;
204 if (w >= 0) {
205 p += w;
206 while (*nice)
207 *p++ = *nice++;
208 }
209}
210
211static void map_1d_info(char **map, int div, char *nice, struct tcm_area *a)
212{
213 sprintf(nice, "%dK", tcm_sizeof(*a) * 4);
214 if (a->p0.y + 1 < a->p1.y) {
215 text_map(map, div, nice, (a->p0.y + a->p1.y) / 2, 0,
216 TILER_WIDTH - 1);
217 } else if (a->p0.y < a->p1.y) {
218 if (strlen(nice) < map_width(div, a->p0.x, TILER_WIDTH - 1))
219 text_map(map, div, nice, a->p0.y, a->p0.x + div,
220 TILER_WIDTH - 1);
221 else if (strlen(nice) < map_width(div, 0, a->p1.x))
222 text_map(map, div, nice, a->p1.y, 0, a->p1.y - div);
223 } else if (strlen(nice) + 1 < map_width(div, a->p0.x, a->p1.x)) {
224 text_map(map, div, nice, a->p0.y, a->p0.x, a->p1.x);
225 }
226}
227
228static void map_2d_info(char **map, int div, char *nice, struct tcm_area *a)
229{
230 sprintf(nice, "(%d*%d)", tcm_awidth(*a), tcm_aheight(*a));
231 if (strlen(nice) + 1 < map_width(div, a->p0.x, a->p1.x))
232 text_map(map, div, nice, (a->p0.y + a->p1.y) / 2, a->p0.x,
233 a->p1.x);
234}
235
236static void debug_allocation_map(struct seq_file *s)
237{
238 int div = 2;
239 int i;
240 char **map, *global_map;
241 struct area_info *ai;
242 struct mem_info *mi;
243 struct tcm_area a, p;
244 static char *m2d = "abcdefghijklmnopqrstuvwxyz"
245 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
246 static char *a2d = ".,:;'\"`~!^-+";
247 char *m2dp = m2d, *a2dp = a2d;
248 char nice[128];
249
250 /* allocate map */
251 map = kzalloc(TILER_HEIGHT * sizeof(*map), GFP_KERNEL);
252 global_map = kzalloc((TILER_WIDTH / div + 1) * TILER_HEIGHT,
253 GFP_KERNEL);
254 if (!map || !global_map) {
255 printk(KERN_ERR "could not allocate map for debug print\n");
256 goto error;
257 }
258 memset(global_map, ' ', (TILER_WIDTH / div + 1) * TILER_HEIGHT);
259 for (i = 0; i < TILER_HEIGHT; i++) {
260 map[i] = global_map + i * (TILER_WIDTH / div + 1);
261 map[i][TILER_WIDTH / div] = 0;
262 }
263
264 /* get all allocations */
265 mutex_lock(&mtx);
266
267 list_for_each_entry(mi, &blocks, global) {
268 if (mi->area.is2d) {
269 ai = mi->parent;
270 fill_map(map, div, &ai->area, *a2dp, false);
271 fill_map(map, div, &mi->area, *m2dp, true);
272 if (!*++a2dp)
273 a2dp = a2d;
274 if (!*++m2dp)
275 m2dp = m2d;
276 map_2d_info(map, div, nice, &mi->area);
277 } else {
278 bool start = read_map_pt(map, div, &mi->area.p0) == ' ';
279 bool end = read_map_pt(map, div, &mi->area.p1) == ' ';
280 tcm_for_each_slice(a, mi->area, p)
281 fill_map(map, div, &a, '=', true);
282 fill_map_pt(map, div, &mi->area.p0, start ? '<' : 'X');
283 fill_map_pt(map, div, &mi->area.p1, end ? '>' : 'X');
284 map_1d_info(map, div, nice, &mi->area);
285 }
286 }
287
288 seq_printf(s, "BEGIN TILER MAP\n");
289 for (i = 0; i < TILER_HEIGHT; i++)
290 seq_printf(s, "%03d:%s\n", i, map[i]);
291 seq_printf(s, "END TILER MAP\n");
292
293 mutex_unlock(&mtx);
294
295error:
296 kfree(map);
297 kfree(global_map);
298}
299
300static int tiler_debug_show(struct seq_file *s, void *unused)
301{
302 void (*func)(struct seq_file *) = s->private;
303 func(s);
304 return 0;
305}
306
307static int tiler_debug_open(struct inode *inode, struct file *file)
308{
309 return single_open(file, tiler_debug_show, inode->i_private);
310}
311
312static const struct file_operations tiler_debug_fops = {
313 .open = tiler_debug_open,
314 .read = seq_read,
315 .llseek = seq_lseek,
316 .release = single_release,
317};
318
166/* 319/*
167 * gid_info handling methods 320 * gid_info handling methods
168 * ========================================================================== 321 * ==========================================================================
@@ -434,6 +587,16 @@ static struct mem_info *get_2d_area(u16 w, u16 h, u16 align, u16 offs, u16 band,
434 587
435 /* remove from reserved list */ 588 /* remove from reserved list */
436 list_del(&mi->global); 589 list_del(&mi->global);
590 if (tiler_alloc_debug & 1)
591 printk(KERN_ERR "(=2d (%d-%d,%d-%d) in (%d-%d,%d-%d) prereserved)\n",
592 mi->area.p0.x, mi->area.p1.x,
593 mi->area.p0.y, mi->area.p1.y,
594 ((struct area_info *) mi->parent)->area.p0.x,
595 ((struct area_info *) mi->parent)->area.p1.x,
596 ((struct area_info *) mi->parent)->area.p0.y,
597 ((struct area_info *) mi->parent)->area.p1.y);
598
599
437 goto done; 600 goto done;
438 } 601 }
439 } 602 }
@@ -454,6 +617,16 @@ static struct mem_info *get_2d_area(u16 w, u16 h, u16 align, u16 offs, u16 band,
454 x = _m_blk_find_fit(w, align, offs, ai, &before); 617 x = _m_blk_find_fit(w, align, offs, ai, &before);
455 if (x) { 618 if (x) {
456 _m_add2area(mi, ai, x - w, w, before); 619 _m_add2area(mi, ai, x - w, w, before);
620
621 if (tiler_alloc_debug & 1)
622 printk(KERN_ERR "(+2d (%d-%d,%d-%d) in (%d-%d,%d-%d) existing)\n",
623 mi->area.p0.x, mi->area.p1.x,
624 mi->area.p0.y, mi->area.p1.y,
625 ((struct area_info *) mi->parent)->area.p0.x,
626 ((struct area_info *) mi->parent)->area.p1.x,
627 ((struct area_info *) mi->parent)->area.p0.y,
628 ((struct area_info *) mi->parent)->area.p1.y);
629
457 goto done; 630 goto done;
458 } 631 }
459 } 632 }
@@ -465,6 +638,13 @@ static struct mem_info *get_2d_area(u16 w, u16 h, u16 align, u16 offs, u16 band,
465 max(band, align), tcm, gi); 638 max(band, align), tcm, gi);
466 if (ai) { 639 if (ai) {
467 _m_add2area(mi, ai, ai->area.p0.x + offs, w, &ai->blocks); 640 _m_add2area(mi, ai, ai->area.p0.x + offs, w, &ai->blocks);
641 if (tiler_alloc_debug & 1)
642 printk(KERN_ERR "(+2d (%d-%d,%d-%d) in (%d-%d,%d-%d) new)\n",
643 mi->area.p0.x, mi->area.p1.x,
644 mi->area.p0.y, mi->area.p1.y,
645 ai->area.p0.x, ai->area.p1.x,
646 ai->area.p0.y, ai->area.p1.y);
647
468 } else { 648 } else {
469 /* clean up */ 649 /* clean up */
470 kfree(mi); 650 kfree(mi);
@@ -608,14 +788,31 @@ static s32 _m_free(struct mem_info *mi)
608 788
609 /* check to see if area needs removing also */ 789 /* check to see if area needs removing also */
610 if (ai && !--ai->nblocks) { 790 if (ai && !--ai->nblocks) {
791 if (tiler_alloc_debug & 1)
792 printk(KERN_ERR "(-2d (%d-%d,%d-%d) in (%d-%d,%d-%d) last)\n",
793 mi->area.p0.x, mi->area.p1.x,
794 mi->area.p0.y, mi->area.p1.y,
795 ai->area.p0.x, ai->area.p1.x,
796 ai->area.p0.y, ai->area.p1.y);
797
611 res = tcm_free(&ai->area); 798 res = tcm_free(&ai->area);
612 list_del(&ai->by_gid); 799 list_del(&ai->by_gid);
613 /* try to remove parent if it became empty */ 800 /* try to remove parent if it became empty */
614 _m_try_free_group(ai->gi); 801 _m_try_free_group(ai->gi);
615 kfree(ai); 802 kfree(ai);
616 ai = NULL; 803 ai = NULL;
617 } 804 } else if (tiler_alloc_debug & 1)
805 printk(KERN_ERR "(-2d (%d-%d,%d-%d) in (%d-%d,%d-%d) remaining)\n",
806 mi->area.p0.x, mi->area.p1.x,
807 mi->area.p0.y, mi->area.p1.y,
808 ai->area.p0.x, ai->area.p1.x,
809 ai->area.p0.y, ai->area.p1.y);
618 } else { 810 } else {
811 if (tiler_alloc_debug & 1)
812 printk(KERN_ERR "(-1d: %d,%d..%d,%d)\n",
813 mi->area.p0.x, mi->area.p0.y,
814 mi->area.p1.x, mi->area.p1.y);
815
619 /* remove 1D area */ 816 /* remove 1D area */
620 res = tcm_free(&mi->area); 817 res = tcm_free(&mi->area);
621 /* try to remove parent if it became empty */ 818 /* try to remove parent if it became empty */
@@ -892,6 +1089,11 @@ static struct mem_info *alloc_area(enum tiler_fmt fmt, u32 width, u32 height,
892 return NULL; 1089 return NULL;
893 } 1090 }
894 1091
1092 if (tiler_alloc_debug & 1)
1093 printk(KERN_ERR "(+1d: %d,%d..%d,%d)\n",
1094 mi->area.p0.x, mi->area.p0.y,
1095 mi->area.p1.x, mi->area.p1.y);
1096
895 mutex_lock(&mtx); 1097 mutex_lock(&mtx);
896 mi->parent = gi; 1098 mi->parent = gi;
897 list_add(&mi->by_area, &gi->onedim); 1099 list_add(&mi->by_area, &gi->onedim);
@@ -1329,6 +1531,18 @@ static s32 __init tiler_init(void)
1329 INIT_LIST_HEAD(&orphan_areas); 1531 INIT_LIST_HEAD(&orphan_areas);
1330 INIT_LIST_HEAD(&orphan_onedim); 1532 INIT_LIST_HEAD(&orphan_onedim);
1331 1533
1534 dbgfs = debugfs_create_dir("tiler", NULL);
1535 if (IS_ERR_OR_NULL(dbgfs))
1536 dev_warn(device, "failed to create debug files.\n");
1537 else
1538 dbg_map = debugfs_create_dir("map", dbgfs);
1539 if (!IS_ERR_OR_NULL(dbg_map))
1540 debugfs_create_file("2x1", S_IRUGO, dbg_map,
1541 &debug_allocation_map, &tiler_debug_fops);
1542 if (!IS_ERR_OR_NULL(dbgfs))
1543 debugfs_create_bool("alloc_debug", S_IRUGO | S_IWUSR, dbgfs,
1544 (u32*)&tiler_alloc_debug);
1545
1332error: 1546error:
1333 /* TODO: error handling for device registration */ 1547 /* TODO: error handling for device registration */
1334 if (r) { 1548 if (r) {
@@ -1348,6 +1562,8 @@ static void __exit tiler_exit(void)
1348 1562
1349 mutex_lock(&mtx); 1563 mutex_lock(&mtx);
1350 1564
1565 debugfs_remove_recursive(dbgfs);
1566
1351 /* free all process data */ 1567 /* free all process data */
1352 tiler.cleanup(); 1568 tiler.cleanup();
1353 1569