From patchwork Fri Dec 16 03:05:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 5805 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id DCD3E23E03 for ; Fri, 16 Dec 2011 03:05:19 +0000 (UTC) Received: from mail-ey0-f180.google.com (mail-ey0-f180.google.com [209.85.215.180]) by fiordland.canonical.com (Postfix) with ESMTP id D136DA18276 for ; Fri, 16 Dec 2011 03:05:19 +0000 (UTC) Received: by mail-ey0-f180.google.com with SMTP id k10so3123076eaa.11 for ; Thu, 15 Dec 2011 19:05:19 -0800 (PST) Received: by 10.205.129.137 with SMTP id hi9mr2596777bkc.90.1324004719514; Thu, 15 Dec 2011 19:05:19 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.129.2 with SMTP id hg2cs59731bkc; Thu, 15 Dec 2011 19:05:19 -0800 (PST) Received: by 10.236.92.168 with SMTP id j28mr8931853yhf.59.1324004717435; Thu, 15 Dec 2011 19:05:17 -0800 (PST) Received: from mail-gx0-f178.google.com (mail-gx0-f178.google.com [209.85.161.178]) by mx.google.com with ESMTPS id b46si6689108yhe.153.2011.12.15.19.05.16 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 15 Dec 2011 19:05:17 -0800 (PST) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.161.178 as permitted sender) client-ip=209.85.161.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.161.178 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass (test mode) header.i=@gmail.com Received: by ggnq4 with SMTP id q4so2944674ggn.37 for ; Thu, 15 Dec 2011 19:05:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=X5xyVx2d3UalqbREAVHAo6t+RVZ2dbhk7u814SetTBY=; b=W3G5hCxVm5Qc72mYQQr2dsMGRFpdxQJXerje8I7W6Sq1eOP8ZQC6EvNgw2PdKZQmZs 4FSLug7/Vf742Ij9XS/IArRMHh0zz7jNRbEKgU07LfJwhhYxQ3M1TpMgCHwheOxH3GB5 CvSaylPI4PM5Ns7c7RdkfW0t2ywntdELYgYeU= Received: by 10.236.129.202 with SMTP id h50mr10132510yhi.1.1324004716834; Thu, 15 Dec 2011 19:05:16 -0800 (PST) Received: from localhost (ppp-70-253-156-7.dsl.rcsntx.swbell.net. [70.253.156.7]) by mx.google.com with ESMTPS id m38sm15709520anq.16.2011.12.15.19.05.15 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 15 Dec 2011 19:05:16 -0800 (PST) Sender: Rob Clark From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: patches@linaro.org, Greg KH , Tomi Valkeinen , Andy Gross , Rob Clark Subject: [PATCH 3/3] drm/omap: add debugfs support Date: Thu, 15 Dec 2011 21:05:17 -0600 Message-Id: <1324004717-20595-3-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1324004717-20595-1-git-send-email-rob.clark@linaro.org> References: <1324004717-20595-1-git-send-email-rob.clark@linaro.org> From: Andy Gross 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 --- drivers/staging/omapdrm/Makefile | 1 + drivers/staging/omapdrm/omap_debugfs.c | 42 +++++++++ drivers/staging/omapdrm/omap_dmm_tiler.c | 149 ++++++++++++++++++++++++++++++ drivers/staging/omapdrm/omap_dmm_tiler.h | 4 + drivers/staging/omapdrm/omap_drv.c | 4 + drivers/staging/omapdrm/omap_drv.h | 5 + 6 files changed, 205 insertions(+), 0 deletions(-) create mode 100644 drivers/staging/omapdrm/omap_debugfs.c diff --git a/drivers/staging/omapdrm/Makefile b/drivers/staging/omapdrm/Makefile index 275054a..592cf69 100644 --- a/drivers/staging/omapdrm/Makefile +++ b/drivers/staging/omapdrm/Makefile @@ -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 \ diff --git a/drivers/staging/omapdrm/omap_debugfs.c b/drivers/staging/omapdrm/omap_debugfs.c new file mode 100644 index 0000000..da920df --- /dev/null +++ b/drivers/staging/omapdrm/omap_debugfs.c @@ -0,0 +1,42 @@ +/* + * drivers/staging/omapdrm/omap_debugfs.c + * + * Copyright (C) 2011 Texas Instruments + * Author: Rob Clark + * + * 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 . + */ + +#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 diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index b182de5..852d944 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -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 diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h index 58aa046..f87cb65 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.h +++ b/drivers/staging/omapdrm/omap_dmm_tiler.h @@ -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); diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 7ecf578..602aa2d 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 = { .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, diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index 263057a..76c4251 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -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);