Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Andy Gross and committed by
Greg Kroah-Hartman
6169a148 af69592a

+205
+1
drivers/staging/omapdrm/Makefile
··· 5 5 6 6 ccflags-y := -Iinclude/drm -Werror 7 7 omapdrm-y := omap_drv.o \ 8 + omap_debugfs.o \ 8 9 omap_crtc.o \ 9 10 omap_encoder.o \ 10 11 omap_connector.o \
+42
drivers/staging/omapdrm/omap_debugfs.c
··· 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
+149
drivers/staging/omapdrm/omap_dmm_tiler.c
··· 679 679 omap_dmm_remove(); 680 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
+4
drivers/staging/omapdrm/omap_dmm_tiler.h
··· 76 76 int omap_dmm_init(struct drm_device *dev); 77 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 83 /* pin/unpin */ 80 84 int tiler_pin(struct tiler_block *block, struct page **pages, 81 85 uint32_t npages, uint32_t roll, bool wait);
+4
drivers/staging/omapdrm/omap_drv.c
··· 726 726 .irq_uninstall = dev_irq_uninstall, 727 727 .irq_handler = dev_irq_handler, 728 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 733 .gem_init_object = omap_gem_init_object, 730 734 .gem_free_object = omap_gem_free_object, 731 735 .gem_vm_ops = &omap_gem_vm_ops,
+5
drivers/staging/omapdrm/omap_drv.h
··· 51 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 59 struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev); 55 60 void omap_fbdev_free(struct drm_device *dev); 56 61