staging: drm/omap: debugfs for object and fb tracking
Add some additional debugfs file to aid in tracking buffer usage. Signed-off-by: Rob Clark <rob@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b33f34d3d1
commit
f6b6036e56
|
@ -20,23 +20,119 @@
|
||||||
#include "omap_drv.h"
|
#include "omap_drv.h"
|
||||||
#include "omap_dmm_tiler.h"
|
#include "omap_dmm_tiler.h"
|
||||||
|
|
||||||
|
#include "drm_fb_helper.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
|
||||||
|
static int gem_show(struct seq_file *m, void *arg)
|
||||||
|
{
|
||||||
|
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||||
|
struct drm_device *dev = node->minor->dev;
|
||||||
|
struct omap_drm_private *priv = dev->dev_private;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = mutex_lock_interruptible(&dev->struct_mutex);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
seq_printf(m, "All Objects:\n");
|
||||||
|
omap_gem_describe_objects(&priv->obj_list, m);
|
||||||
|
|
||||||
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mm_show(struct seq_file *m, void *arg)
|
||||||
|
{
|
||||||
|
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||||
|
struct drm_device *dev = node->minor->dev;
|
||||||
|
return drm_mm_dump_table(m, dev->mm_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fb_show(struct seq_file *m, void *arg)
|
||||||
|
{
|
||||||
|
struct drm_info_node *node = (struct drm_info_node *) m->private;
|
||||||
|
struct drm_device *dev = node->minor->dev;
|
||||||
|
struct omap_drm_private *priv = dev->dev_private;
|
||||||
|
struct drm_framebuffer *fb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = mutex_lock_interruptible(&dev->mode_config.mutex);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = mutex_lock_interruptible(&dev->struct_mutex);
|
||||||
|
if (ret) {
|
||||||
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_printf(m, "fbcon ");
|
||||||
|
omap_framebuffer_describe(priv->fbdev->fb, m);
|
||||||
|
|
||||||
|
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
|
||||||
|
if (fb == priv->fbdev->fb)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
seq_printf(m, "user ");
|
||||||
|
omap_framebuffer_describe(fb, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* list of debufs files that are applicable to all devices */
|
||||||
static struct drm_info_list omap_debugfs_list[] = {
|
static struct drm_info_list omap_debugfs_list[] = {
|
||||||
|
{"gem", gem_show, 0},
|
||||||
|
{"mm", mm_show, 0},
|
||||||
|
{"fb", fb_show, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* list of debugfs files that are specific to devices with dmm/tiler */
|
||||||
|
static struct drm_info_list omap_dmm_debugfs_list[] = {
|
||||||
{"tiler_map", tiler_map_show, 0},
|
{"tiler_map", tiler_map_show, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
int omap_debugfs_init(struct drm_minor *minor)
|
int omap_debugfs_init(struct drm_minor *minor)
|
||||||
{
|
{
|
||||||
return drm_debugfs_create_files(omap_debugfs_list,
|
struct drm_device *dev = minor->dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = drm_debugfs_create_files(omap_debugfs_list,
|
||||||
ARRAY_SIZE(omap_debugfs_list),
|
ARRAY_SIZE(omap_debugfs_list),
|
||||||
minor->debugfs_root, minor);
|
minor->debugfs_root, minor);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev->dev, "could not install omap_debugfs_list\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: only do this if has_dmm.. but this fxn gets called before
|
||||||
|
* dev_load() so we don't know this yet..
|
||||||
|
*/
|
||||||
|
ret = drm_debugfs_create_files(omap_dmm_debugfs_list,
|
||||||
|
ARRAY_SIZE(omap_dmm_debugfs_list),
|
||||||
|
minor->debugfs_root, minor);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev->dev, "could not install omap_dmm_debugfs_list\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void omap_debugfs_cleanup(struct drm_minor *minor)
|
void omap_debugfs_cleanup(struct drm_minor *minor)
|
||||||
{
|
{
|
||||||
drm_debugfs_remove_files(omap_debugfs_list,
|
drm_debugfs_remove_files(omap_debugfs_list,
|
||||||
ARRAY_SIZE(omap_debugfs_list), minor);
|
ARRAY_SIZE(omap_debugfs_list), minor);
|
||||||
|
drm_debugfs_remove_files(omap_dmm_debugfs_list,
|
||||||
|
ARRAY_SIZE(omap_dmm_debugfs_list), minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -573,6 +573,8 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
|
||||||
priv->wq = alloc_workqueue("omapdrm",
|
priv->wq = alloc_workqueue("omapdrm",
|
||||||
WQ_UNBOUND | WQ_NON_REENTRANT, 1);
|
WQ_UNBOUND | WQ_NON_REENTRANT, 1);
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&priv->obj_list);
|
||||||
|
|
||||||
omap_gem_init(dev);
|
omap_gem_init(dev);
|
||||||
|
|
||||||
ret = omap_modeset_init(dev);
|
ret = omap_modeset_init(dev);
|
||||||
|
|
|
@ -42,10 +42,13 @@
|
||||||
struct omap_drm_private {
|
struct omap_drm_private {
|
||||||
unsigned int num_crtcs;
|
unsigned int num_crtcs;
|
||||||
struct drm_crtc *crtcs[8];
|
struct drm_crtc *crtcs[8];
|
||||||
|
|
||||||
unsigned int num_planes;
|
unsigned int num_planes;
|
||||||
struct drm_plane *planes[8];
|
struct drm_plane *planes[8];
|
||||||
|
|
||||||
unsigned int num_encoders;
|
unsigned int num_encoders;
|
||||||
struct drm_encoder *encoders[8];
|
struct drm_encoder *encoders[8];
|
||||||
|
|
||||||
unsigned int num_connectors;
|
unsigned int num_connectors;
|
||||||
struct drm_connector *connectors[8];
|
struct drm_connector *connectors[8];
|
||||||
|
|
||||||
|
@ -53,12 +56,17 @@ struct omap_drm_private {
|
||||||
|
|
||||||
struct workqueue_struct *wq;
|
struct workqueue_struct *wq;
|
||||||
|
|
||||||
|
struct list_head obj_list;
|
||||||
|
|
||||||
bool has_dmm;
|
bool has_dmm;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
int omap_debugfs_init(struct drm_minor *minor);
|
int omap_debugfs_init(struct drm_minor *minor);
|
||||||
void omap_debugfs_cleanup(struct drm_minor *minor);
|
void omap_debugfs_cleanup(struct drm_minor *minor);
|
||||||
|
void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m);
|
||||||
|
void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
|
||||||
|
void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
|
struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev);
|
||||||
|
|
|
@ -277,6 +277,24 @@ void omap_framebuffer_flush(struct drm_framebuffer *fb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
|
||||||
|
{
|
||||||
|
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
|
||||||
|
int i, n = drm_format_num_planes(fb->pixel_format);
|
||||||
|
|
||||||
|
seq_printf(m, "fb: %dx%d@%4.4s\n", fb->width, fb->height,
|
||||||
|
(char *)&fb->pixel_format);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
struct plane *plane = &omap_fb->planes[i];
|
||||||
|
seq_printf(m, " %d: offset=%d pitch=%d, obj: ",
|
||||||
|
i, plane->offset, plane->pitch);
|
||||||
|
omap_gem_describe(plane->bo, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
|
struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
|
||||||
struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd)
|
struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,8 @@ int _drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size);
|
||||||
struct omap_gem_object {
|
struct omap_gem_object {
|
||||||
struct drm_gem_object base;
|
struct drm_gem_object base;
|
||||||
|
|
||||||
|
struct list_head mm_list;
|
||||||
|
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
/** width/height for tiled formats (rounded up to slot boundaries) */
|
/** width/height for tiled formats (rounded up to slot boundaries) */
|
||||||
|
@ -254,13 +256,17 @@ static void omap_gem_detach_pages(struct drm_gem_object *obj)
|
||||||
/** get mmap offset */
|
/** get mmap offset */
|
||||||
static uint64_t mmap_offset(struct drm_gem_object *obj)
|
static uint64_t mmap_offset(struct drm_gem_object *obj)
|
||||||
{
|
{
|
||||||
|
struct drm_device *dev = obj->dev;
|
||||||
|
|
||||||
|
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
|
||||||
|
|
||||||
if (!obj->map_list.map) {
|
if (!obj->map_list.map) {
|
||||||
/* Make it mmapable */
|
/* Make it mmapable */
|
||||||
size_t size = omap_gem_mmap_size(obj);
|
size_t size = omap_gem_mmap_size(obj);
|
||||||
int ret = _drm_gem_create_mmap_offset_size(obj, size);
|
int ret = _drm_gem_create_mmap_offset_size(obj, size);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(obj->dev->dev, "could not allocate mmap offset");
|
dev_err(dev->dev, "could not allocate mmap offset\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -764,6 +770,56 @@ void *omap_gem_vaddr(struct drm_gem_object *obj)
|
||||||
return omap_obj->vaddr;
|
return omap_obj->vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_FS
|
||||||
|
void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = obj->dev;
|
||||||
|
struct omap_gem_object *omap_obj = to_omap_bo(obj);
|
||||||
|
uint64_t off = 0;
|
||||||
|
|
||||||
|
WARN_ON(! mutex_is_locked(&dev->struct_mutex));
|
||||||
|
|
||||||
|
if (obj->map_list.map)
|
||||||
|
off = (uint64_t)obj->map_list.hash.key;
|
||||||
|
|
||||||
|
seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d",
|
||||||
|
omap_obj->flags, obj->name, obj->refcount.refcount.counter,
|
||||||
|
off, omap_obj->paddr, omap_obj->paddr_cnt,
|
||||||
|
omap_obj->vaddr, omap_obj->roll);
|
||||||
|
|
||||||
|
if (omap_obj->flags & OMAP_BO_TILED) {
|
||||||
|
seq_printf(m, " %dx%d", omap_obj->width, omap_obj->height);
|
||||||
|
if (omap_obj->block) {
|
||||||
|
struct tcm_area *area = &omap_obj->block->area;
|
||||||
|
seq_printf(m, " (%dx%d, %dx%d)",
|
||||||
|
area->p0.x, area->p0.y,
|
||||||
|
area->p1.x, area->p1.y);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
seq_printf(m, " %d", obj->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_printf(m, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void omap_gem_describe_objects(struct list_head *list, struct seq_file *m)
|
||||||
|
{
|
||||||
|
struct omap_gem_object *omap_obj;
|
||||||
|
int count = 0;
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
list_for_each_entry(omap_obj, list, mm_list) {
|
||||||
|
struct drm_gem_object *obj = &omap_obj->base;
|
||||||
|
seq_printf(m, " ");
|
||||||
|
omap_gem_describe(obj, m);
|
||||||
|
count++;
|
||||||
|
size += obj->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_printf(m, "Total %d objects, %zu bytes\n", count, size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Buffer Synchronization:
|
/* Buffer Synchronization:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1030,6 +1086,10 @@ void omap_gem_free_object(struct drm_gem_object *obj)
|
||||||
|
|
||||||
evict(obj);
|
evict(obj);
|
||||||
|
|
||||||
|
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
|
||||||
|
|
||||||
|
list_del(&omap_obj->mm_list);
|
||||||
|
|
||||||
if (obj->map_list.map) {
|
if (obj->map_list.map) {
|
||||||
drm_gem_free_mmap_offset(obj);
|
drm_gem_free_mmap_offset(obj);
|
||||||
}
|
}
|
||||||
|
@ -1130,6 +1190,8 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_add(&omap_obj->mm_list, &priv->obj_list);
|
||||||
|
|
||||||
obj = &omap_obj->base;
|
obj = &omap_obj->base;
|
||||||
|
|
||||||
if ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm) {
|
if ((flags & OMAP_BO_SCANOUT) && !priv->has_dmm) {
|
||||||
|
|
Loading…
Reference in New Issue