diff options
author | Andy Gross <andy.gross@ti.com> | 2011-12-15 22:05:17 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-16 13:59:26 -0500 |
commit | 6169a1488fe2f76e80bd49c18e41be5bbbf29f3f (patch) | |
tree | 671ba667b57529010a8d3ce9e0ced299d814c3c7 /drivers/staging/omapdrm | |
parent | af69592aa098ff8cd640e8109ba946db3c1cdb4e (diff) |
staging: drm/omap: add debugfs support
Right now just a tiler_map file to dump a 2d map of which areas in
tiler/dmm have pinned buffers (or reservations). In the future more
could be added.
Signed-off-by: Rob Clark <rob@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/omapdrm')
-rw-r--r-- | drivers/staging/omapdrm/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/omapdrm/omap_debugfs.c | 42 | ||||
-rw-r--r-- | drivers/staging/omapdrm/omap_dmm_tiler.c | 149 | ||||
-rw-r--r-- | drivers/staging/omapdrm/omap_dmm_tiler.h | 4 | ||||
-rw-r--r-- | drivers/staging/omapdrm/omap_drv.c | 4 | ||||
-rw-r--r-- | drivers/staging/omapdrm/omap_drv.h | 5 |
6 files changed, 205 insertions, 0 deletions
diff --git a/drivers/staging/omapdrm/Makefile b/drivers/staging/omapdrm/Makefile index 275054a3451..592cf69020c 100644 --- a/drivers/staging/omapdrm/Makefile +++ b/drivers/staging/omapdrm/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | ccflags-y := -Iinclude/drm -Werror | 6 | ccflags-y := -Iinclude/drm -Werror |
7 | omapdrm-y := omap_drv.o \ | 7 | omapdrm-y := omap_drv.o \ |
8 | omap_debugfs.o \ | ||
8 | omap_crtc.o \ | 9 | omap_crtc.o \ |
9 | omap_encoder.o \ | 10 | omap_encoder.o \ |
10 | omap_connector.o \ | 11 | omap_connector.o \ |
diff --git a/drivers/staging/omapdrm/omap_debugfs.c b/drivers/staging/omapdrm/omap_debugfs.c new file mode 100644 index 00000000000..da920dfdc59 --- /dev/null +++ b/drivers/staging/omapdrm/omap_debugfs.c | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * drivers/staging/omapdrm/omap_debugfs.c | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments | ||
5 | * Author: Rob Clark <rob.clark@linaro.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include "omap_drv.h" | ||
21 | #include "omap_dmm_tiler.h" | ||
22 | |||
23 | #ifdef CONFIG_DEBUG_FS | ||
24 | |||
25 | static struct drm_info_list omap_debugfs_list[] = { | ||
26 | {"tiler_map", tiler_map_show, 0}, | ||
27 | }; | ||
28 | |||
29 | int omap_debugfs_init(struct drm_minor *minor) | ||
30 | { | ||
31 | return drm_debugfs_create_files(omap_debugfs_list, | ||
32 | ARRAY_SIZE(omap_debugfs_list), | ||
33 | minor->debugfs_root, minor); | ||
34 | } | ||
35 | |||
36 | void omap_debugfs_cleanup(struct drm_minor *minor) | ||
37 | { | ||
38 | drm_debugfs_remove_files(omap_debugfs_list, | ||
39 | ARRAY_SIZE(omap_debugfs_list), minor); | ||
40 | } | ||
41 | |||
42 | #endif | ||
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index b182de537b4..852d9440f72 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c | |||
@@ -679,3 +679,152 @@ fail: | |||
679 | omap_dmm_remove(); | 679 | omap_dmm_remove(); |
680 | return ret; | 680 | return ret; |
681 | } | 681 | } |
682 | |||
683 | /* | ||
684 | * debugfs support | ||
685 | */ | ||
686 | |||
687 | #ifdef CONFIG_DEBUG_FS | ||
688 | |||
689 | static const char *alphabet = "abcdefghijklmnopqrstuvwxyz" | ||
690 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | ||
691 | static const char *special = ".,:;'\"`~!^-+"; | ||
692 | |||
693 | static void fill_map(char **map, int xdiv, int ydiv, struct tcm_area *a, | ||
694 | char c, bool ovw) | ||
695 | { | ||
696 | int x, y; | ||
697 | for (y = a->p0.y / ydiv; y <= a->p1.y / ydiv; y++) | ||
698 | for (x = a->p0.x / xdiv; x <= a->p1.x / xdiv; x++) | ||
699 | if (map[y][x] == ' ' || ovw) | ||
700 | map[y][x] = c; | ||
701 | } | ||
702 | |||
703 | static void fill_map_pt(char **map, int xdiv, int ydiv, struct tcm_pt *p, | ||
704 | char c) | ||
705 | { | ||
706 | map[p->y / ydiv][p->x / xdiv] = c; | ||
707 | } | ||
708 | |||
709 | static char read_map_pt(char **map, int xdiv, int ydiv, struct tcm_pt *p) | ||
710 | { | ||
711 | return map[p->y / ydiv][p->x / xdiv]; | ||
712 | } | ||
713 | |||
714 | static int map_width(int xdiv, int x0, int x1) | ||
715 | { | ||
716 | return (x1 / xdiv) - (x0 / xdiv) + 1; | ||
717 | } | ||
718 | |||
719 | static void text_map(char **map, int xdiv, char *nice, int yd, int x0, int x1) | ||
720 | { | ||
721 | char *p = map[yd] + (x0 / xdiv); | ||
722 | int w = (map_width(xdiv, x0, x1) - strlen(nice)) / 2; | ||
723 | if (w >= 0) { | ||
724 | p += w; | ||
725 | while (*nice) | ||
726 | *p++ = *nice++; | ||
727 | } | ||
728 | } | ||
729 | |||
730 | static void map_1d_info(char **map, int xdiv, int ydiv, char *nice, | ||
731 | struct tcm_area *a) | ||
732 | { | ||
733 | sprintf(nice, "%dK", tcm_sizeof(*a) * 4); | ||
734 | if (a->p0.y + 1 < a->p1.y) { | ||
735 | text_map(map, xdiv, nice, (a->p0.y + a->p1.y) / 2 / ydiv, 0, | ||
736 | 256 - 1); | ||
737 | } else if (a->p0.y < a->p1.y) { | ||
738 | if (strlen(nice) < map_width(xdiv, a->p0.x, 256 - 1)) | ||
739 | text_map(map, xdiv, nice, a->p0.y / ydiv, | ||
740 | a->p0.x + xdiv, 256 - 1); | ||
741 | else if (strlen(nice) < map_width(xdiv, 0, a->p1.x)) | ||
742 | text_map(map, xdiv, nice, a->p1.y / ydiv, | ||
743 | 0, a->p1.y - xdiv); | ||
744 | } else if (strlen(nice) + 1 < map_width(xdiv, a->p0.x, a->p1.x)) { | ||
745 | text_map(map, xdiv, nice, a->p0.y / ydiv, a->p0.x, a->p1.x); | ||
746 | } | ||
747 | } | ||
748 | |||
749 | static void map_2d_info(char **map, int xdiv, int ydiv, char *nice, | ||
750 | struct tcm_area *a) | ||
751 | { | ||
752 | sprintf(nice, "(%d*%d)", tcm_awidth(*a), tcm_aheight(*a)); | ||
753 | if (strlen(nice) + 1 < map_width(xdiv, a->p0.x, a->p1.x)) | ||
754 | text_map(map, xdiv, nice, (a->p0.y + a->p1.y) / 2 / ydiv, | ||
755 | a->p0.x, a->p1.x); | ||
756 | } | ||
757 | |||
758 | int tiler_map_show(struct seq_file *s, void *arg) | ||
759 | { | ||
760 | int xdiv = 2, ydiv = 1; | ||
761 | char **map = NULL, *global_map; | ||
762 | struct tiler_block *block; | ||
763 | struct tcm_area a, p; | ||
764 | int i; | ||
765 | const char *m2d = alphabet; | ||
766 | const char *a2d = special; | ||
767 | const char *m2dp = m2d, *a2dp = a2d; | ||
768 | char nice[128]; | ||
769 | int h_adj = omap_dmm->lut_height / ydiv; | ||
770 | int w_adj = omap_dmm->lut_width / xdiv; | ||
771 | unsigned long flags; | ||
772 | |||
773 | map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL); | ||
774 | global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL); | ||
775 | |||
776 | if (!map || !global_map) | ||
777 | goto error; | ||
778 | |||
779 | memset(global_map, ' ', (w_adj + 1) * h_adj); | ||
780 | for (i = 0; i < omap_dmm->lut_height; i++) { | ||
781 | map[i] = global_map + i * (w_adj + 1); | ||
782 | map[i][w_adj] = 0; | ||
783 | } | ||
784 | spin_lock_irqsave(&omap_dmm->list_lock, flags); | ||
785 | |||
786 | list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) { | ||
787 | if (block->fmt != TILFMT_PAGE) { | ||
788 | fill_map(map, xdiv, ydiv, &block->area, *m2dp, true); | ||
789 | if (!*++a2dp) | ||
790 | a2dp = a2d; | ||
791 | if (!*++m2dp) | ||
792 | m2dp = m2d; | ||
793 | map_2d_info(map, xdiv, ydiv, nice, &block->area); | ||
794 | } else { | ||
795 | bool start = read_map_pt(map, xdiv, ydiv, | ||
796 | &block->area.p0) | ||
797 | == ' '; | ||
798 | bool end = read_map_pt(map, xdiv, ydiv, &block->area.p1) | ||
799 | == ' '; | ||
800 | tcm_for_each_slice(a, block->area, p) | ||
801 | fill_map(map, xdiv, ydiv, &a, '=', true); | ||
802 | fill_map_pt(map, xdiv, ydiv, &block->area.p0, | ||
803 | start ? '<' : 'X'); | ||
804 | fill_map_pt(map, xdiv, ydiv, &block->area.p1, | ||
805 | end ? '>' : 'X'); | ||
806 | map_1d_info(map, xdiv, ydiv, nice, &block->area); | ||
807 | } | ||
808 | } | ||
809 | |||
810 | spin_unlock_irqrestore(&omap_dmm->list_lock, flags); | ||
811 | |||
812 | if (s) { | ||
813 | seq_printf(s, "BEGIN DMM TILER MAP\n"); | ||
814 | for (i = 0; i < 128; i++) | ||
815 | seq_printf(s, "%03d:%s\n", i, map[i]); | ||
816 | seq_printf(s, "END TILER MAP\n"); | ||
817 | } else { | ||
818 | dev_dbg(omap_dmm->dev, "BEGIN DMM TILER MAP\n"); | ||
819 | for (i = 0; i < 128; i++) | ||
820 | dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]); | ||
821 | dev_dbg(omap_dmm->dev, "END TILER MAP\n"); | ||
822 | } | ||
823 | |||
824 | error: | ||
825 | kfree(map); | ||
826 | kfree(global_map); | ||
827 | |||
828 | return 0; | ||
829 | } | ||
830 | #endif | ||
diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h index 58aa046233c..f87cb657d68 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.h +++ b/drivers/staging/omapdrm/omap_dmm_tiler.h | |||
@@ -76,6 +76,10 @@ struct tiler_block { | |||
76 | int omap_dmm_init(struct drm_device *dev); | 76 | int omap_dmm_init(struct drm_device *dev); |
77 | int omap_dmm_remove(void); | 77 | int omap_dmm_remove(void); |
78 | 78 | ||
79 | #ifdef CONFIG_DEBUG_FS | ||
80 | int tiler_map_show(struct seq_file *s, void *arg); | ||
81 | #endif | ||
82 | |||
79 | /* pin/unpin */ | 83 | /* pin/unpin */ |
80 | int tiler_pin(struct tiler_block *block, struct page **pages, | 84 | int tiler_pin(struct tiler_block *block, struct page **pages, |
81 | uint32_t npages, uint32_t roll, bool wait); | 85 | uint32_t npages, uint32_t roll, bool wait); |
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 7ecf578f552..602aa2dd49c 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c | |||
@@ -726,6 +726,10 @@ static struct drm_driver omap_drm_driver = { | |||
726 | .irq_uninstall = dev_irq_uninstall, | 726 | .irq_uninstall = dev_irq_uninstall, |
727 | .irq_handler = dev_irq_handler, | 727 | .irq_handler = dev_irq_handler, |
728 | .reclaim_buffers = drm_core_reclaim_buffers, | 728 | .reclaim_buffers = drm_core_reclaim_buffers, |
729 | #ifdef CONFIG_DEBUG_FS | ||
730 | .debugfs_init = omap_debugfs_init, | ||
731 | .debugfs_cleanup = omap_debugfs_cleanup, | ||
732 | #endif | ||
729 | .gem_init_object = omap_gem_init_object, | 733 | .gem_init_object = omap_gem_init_object, |
730 | .gem_free_object = omap_gem_free_object, | 734 | .gem_free_object = omap_gem_free_object, |
731 | .gem_vm_ops = &omap_gem_vm_ops, | 735 | .gem_vm_ops = &omap_gem_vm_ops, |
diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index 263057ad621..76c42515ecc 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h | |||
@@ -51,6 +51,11 @@ struct omap_drm_private { | |||
51 | bool has_dmm; | 51 | bool has_dmm; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #ifdef CONFIG_DEBUG_FS | ||
55 | int omap_debugfs_init(struct drm_minor *minor); | ||
56 | void omap_debugfs_cleanup(struct drm_minor *minor); | ||
57 | #endif | ||
58 | |||
54 | struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev); | 59 | struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev); |
55 | void omap_fbdev_free(struct drm_device *dev); | 60 | void omap_fbdev_free(struct drm_device *dev); |
56 | 61 | ||