mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 07:34:12 +08:00
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>
This commit is contained in:
parent
af69592aa0
commit
6169a1488f
@ -5,6 +5,7 @@
|
||||
|
||||
ccflags-y := -Iinclude/drm -Werror
|
||||
omapdrm-y := omap_drv.o \
|
||||
omap_debugfs.o \
|
||||
omap_crtc.o \
|
||||
omap_encoder.o \
|
||||
omap_connector.o \
|
||||
|
42
drivers/staging/omapdrm/omap_debugfs.c
Normal file
42
drivers/staging/omapdrm/omap_debugfs.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* drivers/staging/omapdrm/omap_debugfs.c
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments
|
||||
* Author: Rob Clark <rob.clark@linaro.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "omap_drv.h"
|
||||
#include "omap_dmm_tiler.h"
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
static struct drm_info_list omap_debugfs_list[] = {
|
||||
{"tiler_map", tiler_map_show, 0},
|
||||
};
|
||||
|
||||
int omap_debugfs_init(struct drm_minor *minor)
|
||||
{
|
||||
return drm_debugfs_create_files(omap_debugfs_list,
|
||||
ARRAY_SIZE(omap_debugfs_list),
|
||||
minor->debugfs_root, minor);
|
||||
}
|
||||
|
||||
void omap_debugfs_cleanup(struct drm_minor *minor)
|
||||
{
|
||||
drm_debugfs_remove_files(omap_debugfs_list,
|
||||
ARRAY_SIZE(omap_debugfs_list), minor);
|
||||
}
|
||||
|
||||
#endif
|
@ -679,3 +679,152 @@ fail:
|
||||
omap_dmm_remove();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* debugfs support
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
static const char *alphabet = "abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
static const char *special = ".,:;'\"`~!^-+";
|
||||
|
||||
static void fill_map(char **map, int xdiv, int ydiv, struct tcm_area *a,
|
||||
char c, bool ovw)
|
||||
{
|
||||
int x, y;
|
||||
for (y = a->p0.y / ydiv; y <= a->p1.y / ydiv; y++)
|
||||
for (x = a->p0.x / xdiv; x <= a->p1.x / xdiv; x++)
|
||||
if (map[y][x] == ' ' || ovw)
|
||||
map[y][x] = c;
|
||||
}
|
||||
|
||||
static void fill_map_pt(char **map, int xdiv, int ydiv, struct tcm_pt *p,
|
||||
char c)
|
||||
{
|
||||
map[p->y / ydiv][p->x / xdiv] = c;
|
||||
}
|
||||
|
||||
static char read_map_pt(char **map, int xdiv, int ydiv, struct tcm_pt *p)
|
||||
{
|
||||
return map[p->y / ydiv][p->x / xdiv];
|
||||
}
|
||||
|
||||
static int map_width(int xdiv, int x0, int x1)
|
||||
{
|
||||
return (x1 / xdiv) - (x0 / xdiv) + 1;
|
||||
}
|
||||
|
||||
static void text_map(char **map, int xdiv, char *nice, int yd, int x0, int x1)
|
||||
{
|
||||
char *p = map[yd] + (x0 / xdiv);
|
||||
int w = (map_width(xdiv, x0, x1) - strlen(nice)) / 2;
|
||||
if (w >= 0) {
|
||||
p += w;
|
||||
while (*nice)
|
||||
*p++ = *nice++;
|
||||
}
|
||||
}
|
||||
|
||||
static void map_1d_info(char **map, int xdiv, int ydiv, char *nice,
|
||||
struct tcm_area *a)
|
||||
{
|
||||
sprintf(nice, "%dK", tcm_sizeof(*a) * 4);
|
||||
if (a->p0.y + 1 < a->p1.y) {
|
||||
text_map(map, xdiv, nice, (a->p0.y + a->p1.y) / 2 / ydiv, 0,
|
||||
256 - 1);
|
||||
} else if (a->p0.y < a->p1.y) {
|
||||
if (strlen(nice) < map_width(xdiv, a->p0.x, 256 - 1))
|
||||
text_map(map, xdiv, nice, a->p0.y / ydiv,
|
||||
a->p0.x + xdiv, 256 - 1);
|
||||
else if (strlen(nice) < map_width(xdiv, 0, a->p1.x))
|
||||
text_map(map, xdiv, nice, a->p1.y / ydiv,
|
||||
0, a->p1.y - xdiv);
|
||||
} else if (strlen(nice) + 1 < map_width(xdiv, a->p0.x, a->p1.x)) {
|
||||
text_map(map, xdiv, nice, a->p0.y / ydiv, a->p0.x, a->p1.x);
|
||||
}
|
||||
}
|
||||
|
||||
static void map_2d_info(char **map, int xdiv, int ydiv, char *nice,
|
||||
struct tcm_area *a)
|
||||
{
|
||||
sprintf(nice, "(%d*%d)", tcm_awidth(*a), tcm_aheight(*a));
|
||||
if (strlen(nice) + 1 < map_width(xdiv, a->p0.x, a->p1.x))
|
||||
text_map(map, xdiv, nice, (a->p0.y + a->p1.y) / 2 / ydiv,
|
||||
a->p0.x, a->p1.x);
|
||||
}
|
||||
|
||||
int tiler_map_show(struct seq_file *s, void *arg)
|
||||
{
|
||||
int xdiv = 2, ydiv = 1;
|
||||
char **map = NULL, *global_map;
|
||||
struct tiler_block *block;
|
||||
struct tcm_area a, p;
|
||||
int i;
|
||||
const char *m2d = alphabet;
|
||||
const char *a2d = special;
|
||||
const char *m2dp = m2d, *a2dp = a2d;
|
||||
char nice[128];
|
||||
int h_adj = omap_dmm->lut_height / ydiv;
|
||||
int w_adj = omap_dmm->lut_width / xdiv;
|
||||
unsigned long flags;
|
||||
|
||||
map = kzalloc(h_adj * sizeof(*map), GFP_KERNEL);
|
||||
global_map = kzalloc((w_adj + 1) * h_adj, GFP_KERNEL);
|
||||
|
||||
if (!map || !global_map)
|
||||
goto error;
|
||||
|
||||
memset(global_map, ' ', (w_adj + 1) * h_adj);
|
||||
for (i = 0; i < omap_dmm->lut_height; i++) {
|
||||
map[i] = global_map + i * (w_adj + 1);
|
||||
map[i][w_adj] = 0;
|
||||
}
|
||||
spin_lock_irqsave(&omap_dmm->list_lock, flags);
|
||||
|
||||
list_for_each_entry(block, &omap_dmm->alloc_head, alloc_node) {
|
||||
if (block->fmt != TILFMT_PAGE) {
|
||||
fill_map(map, xdiv, ydiv, &block->area, *m2dp, true);
|
||||
if (!*++a2dp)
|
||||
a2dp = a2d;
|
||||
if (!*++m2dp)
|
||||
m2dp = m2d;
|
||||
map_2d_info(map, xdiv, ydiv, nice, &block->area);
|
||||
} else {
|
||||
bool start = read_map_pt(map, xdiv, ydiv,
|
||||
&block->area.p0)
|
||||
== ' ';
|
||||
bool end = read_map_pt(map, xdiv, ydiv, &block->area.p1)
|
||||
== ' ';
|
||||
tcm_for_each_slice(a, block->area, p)
|
||||
fill_map(map, xdiv, ydiv, &a, '=', true);
|
||||
fill_map_pt(map, xdiv, ydiv, &block->area.p0,
|
||||
start ? '<' : 'X');
|
||||
fill_map_pt(map, xdiv, ydiv, &block->area.p1,
|
||||
end ? '>' : 'X');
|
||||
map_1d_info(map, xdiv, ydiv, nice, &block->area);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&omap_dmm->list_lock, flags);
|
||||
|
||||
if (s) {
|
||||
seq_printf(s, "BEGIN DMM TILER MAP\n");
|
||||
for (i = 0; i < 128; i++)
|
||||
seq_printf(s, "%03d:%s\n", i, map[i]);
|
||||
seq_printf(s, "END TILER MAP\n");
|
||||
} else {
|
||||
dev_dbg(omap_dmm->dev, "BEGIN DMM TILER MAP\n");
|
||||
for (i = 0; i < 128; i++)
|
||||
dev_dbg(omap_dmm->dev, "%03d:%s\n", i, map[i]);
|
||||
dev_dbg(omap_dmm->dev, "END TILER MAP\n");
|
||||
}
|
||||
|
||||
error:
|
||||
kfree(map);
|
||||
kfree(global_map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -76,6 +76,10 @@ struct tiler_block {
|
||||
int omap_dmm_init(struct drm_device *dev);
|
||||
int omap_dmm_remove(void);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
int tiler_map_show(struct seq_file *s, void *arg);
|
||||
#endif
|
||||
|
||||
/* pin/unpin */
|
||||
int tiler_pin(struct tiler_block *block, struct page **pages,
|
||||
uint32_t npages, uint32_t roll, bool wait);
|
||||
|
@ -726,6 +726,10 @@ static struct drm_driver omap_drm_driver = {
|
||||
.irq_uninstall = dev_irq_uninstall,
|
||||
.irq_handler = dev_irq_handler,
|
||||
.reclaim_buffers = drm_core_reclaim_buffers,
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
.debugfs_init = omap_debugfs_init,
|
||||
.debugfs_cleanup = omap_debugfs_cleanup,
|
||||
#endif
|
||||
.gem_init_object = omap_gem_init_object,
|
||||
.gem_free_object = omap_gem_free_object,
|
||||
.gem_vm_ops = &omap_gem_vm_ops,
|
||||
|
@ -51,6 +51,11 @@ struct omap_drm_private {
|
||||
bool has_dmm;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
int omap_debugfs_init(struct drm_minor *minor);
|
||||
void omap_debugfs_cleanup(struct drm_minor *minor);
|
||||
#endif
|
||||
|
||||
struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
|
||||
void omap_fbdev_free(struct drm_device *dev);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user