From 2385bc45ef8fb58def46c116673cb11f3ba38c91 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Fri, 4 Nov 2011 14:00:13 +0200 Subject: video: tegra: host: Enhance FIFO/GATHER debug_dump Enhance nvhost_debug_dump() output, as follows: - Swap FIFO and GATHER dump so that even if GATHER dump blows out seq_printf 1k buffer, we still have FIFO information; - Write FIFO signature pattern (0xd???d???) to indirect save input data to help pinpoint FIFO position within debug dumps; - Prevent long data sequences from blowing out the seq_printf 1k buffer, by limiting such sequences to 64 words. Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/62424 (cherry picked from commit cb37e4212b78546411b33b32044f30feb0579b86) Change-Id: Ia2695c502fa0c7b755ef2ae51260650c7d67bf86 Reviewed-on: http://git-master/r/64061 Reviewed-by: Yu-Huan Hsu --- drivers/video/tegra/host/debug.c | 3 +-- drivers/video/tegra/host/nvhost_cdma.h | 1 + drivers/video/tegra/host/nvhost_syncpt.c | 3 ++- drivers/video/tegra/host/t20/3dctx_t20.c | 19 +++++++++----- drivers/video/tegra/host/t20/debug_t20.c | 43 ++++++++++++++++++++++++-------- drivers/video/tegra/host/t30/3dctx_t30.c | 19 ++++++++++---- 6 files changed, 64 insertions(+), 24 deletions(-) diff --git a/drivers/video/tegra/host/debug.c b/drivers/video/tegra/host/debug.c index 7003bcef69d8..8453f68054fb 100644 --- a/drivers/video/tegra/host/debug.c +++ b/drivers/video/tegra/host/debug.c @@ -52,8 +52,8 @@ static void show_channels(struct nvhost_master *m, struct output *o) mutex_lock(&ch->reflock); if (ch->refcount) { mutex_lock(&ch->cdma.lock); - m->op.debug.show_channel_cdma(m, o, i); m->op.debug.show_channel_fifo(m, o, i); + m->op.debug.show_channel_cdma(m, o, i); mutex_unlock(&ch->cdma.lock); } mutex_unlock(&ch->reflock); @@ -73,7 +73,6 @@ static void show_syncpts(struct nvhost_master *m, struct output *o) nvhost_debug_output(o, "id %d (%s) min %d max %d\n", i, m->op.syncpt.name(&m->syncpt, i), nvhost_syncpt_update_min(&m->syncpt, i), max); - } for (i = 0; i < m->syncpt.nb_bases; i++) { diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h index e0a034d4bdc6..ae87d13f137f 100644 --- a/drivers/video/tegra/host/nvhost_cdma.h +++ b/drivers/video/tegra/host/nvhost_cdma.h @@ -135,6 +135,7 @@ void nvhost_cdma_stop(struct nvhost_cdma *cdma); int nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_userctx_timeout *timeout); void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2); +#define NVHOST_CDMA_PUSH_GATHER_CTXSAVE 0xffffffff void nvhost_cdma_push_gather(struct nvhost_cdma *cdma, struct nvmap_client *client, struct nvmap_handle *handle, u32 op1, u32 op2); diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c index 5207c0a2d810..51d79f06d178 100644 --- a/drivers/video/tegra/host/nvhost_syncpt.c +++ b/drivers/video/tegra/host/nvhost_syncpt.c @@ -214,7 +214,8 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, if (check_count > MAX_STUCK_CHECK_COUNT) { if (low_timeout) { dev_warn(&syncpt_to_dev(sp)->pdev->dev, - "is timeout %d too low?\n", low_timeout); + "is timeout %d too low?\n", + low_timeout); } nvhost_debug_dump(syncpt_to_dev(sp)); BUG(); diff --git a/drivers/video/tegra/host/t20/3dctx_t20.c b/drivers/video/tegra/host/t20/3dctx_t20.c index 7ac1b5e118cd..d0609fb61976 100644 --- a/drivers/video/tegra/host/t20/3dctx_t20.c +++ b/drivers/video/tegra/host/t20/3dctx_t20.c @@ -138,8 +138,8 @@ static void save_push_v0(struct nvhost_cdma *cdma, struct nvhost_hwctx *ctx) { nvhost_cdma_push_gather(cdma, - cdma_to_channel(cdma)->dev->nvmap, - nvmap_ref_to_handle(nvhost_3dctx_save_buf), + (void *)NVHOST_CDMA_PUSH_GATHER_CTXSAVE, + (void *)NVHOST_CDMA_PUSH_GATHER_CTXSAVE, nvhost_opcode_gather(save_size), save_phys); } @@ -260,7 +260,17 @@ static void __init setup_save_regs(struct save_info *info, break; } if (ptr) { - memset(ptr, 0, count * 4); + /* SAVE cases only: reserve room for incoming data */ + u32 k = 0; + /* + * Create a signature pattern for indirect data (which + * will be overwritten by true incoming data) for + * better deducing where we are in a long command + * sequence, when given only a FIFO snapshot for debug + * purposes. + */ + for (k = 0; k < count; k++) + *(ptr + k) = 0xd000d000 | (offset << 16) | k; ptr += count; } save_count += count; @@ -332,9 +342,6 @@ static void ctx3d_save_service(struct nvhost_hwctx *ctx) nvhost_syncpt_cpu_incr(&ctx->channel->dev->syncpt, NVSYNCPT_3D); } - -/*** savers ***/ - int __init t20_nvhost_3dctx_handler_init(struct nvhost_hwctx_handler *h) { struct nvhost_channel *ch; diff --git a/drivers/video/tegra/host/t20/debug_t20.c b/drivers/video/tegra/host/t20/debug_t20.c index 5acad0d43132..84267c9a9018 100644 --- a/drivers/video/tegra/host/t20/debug_t20.c +++ b/drivers/video/tegra/host/t20/debug_t20.c @@ -104,10 +104,6 @@ static int show_channel_command(struct output *o, u32 addr, u32 val, int *count) } } -/* - * TODO: This uses ioremap_xxx on memory which is deprecated. - * Also, it won't work properly with SMMU. - */ static void show_channel_gather(struct output *o, u32 addr, phys_addr_t phys_addr, u32 words, struct nvhost_cdma *cdma); @@ -115,6 +111,8 @@ static void show_channel_gather(struct output *o, u32 addr, static void show_channel_word(struct output *o, int *state, int *count, u32 addr, u32 val, struct nvhost_cdma *cdma) { + static int start_count, dont_print; + switch (*state) { case NVHOST_DBG_STATE_CMD: if (addr) @@ -123,6 +121,8 @@ static void show_channel_word(struct output *o, int *state, int *count, nvhost_debug_output(o, "%08x:", val); *state = show_channel_command(o, addr, val, count); + dont_print = 0; + start_count = *count; if (*state == NVHOST_DBG_STATE_DATA && *count == 0) { *state = NVHOST_DBG_STATE_CMD; nvhost_debug_output(o, "])\n"); @@ -131,7 +131,14 @@ static void show_channel_word(struct output *o, int *state, int *count, case NVHOST_DBG_STATE_DATA: (*count)--; - nvhost_debug_output(o, "%08x%s", val, *count > 0 ? ", " : "])\n"); + if (start_count - *count < 64) + nvhost_debug_output(o, "%08x%s", + val, *count > 0 ? ", " : "])\n"); + else if (!dont_print && (*count > 0)) { + nvhost_debug_output(o, "[truncated; %d more words]\n", + *count); + dont_print = 1; + } if (*count == 0) *state = NVHOST_DBG_STATE_CMD; break; @@ -139,8 +146,10 @@ static void show_channel_word(struct output *o, int *state, int *count, case NVHOST_DBG_STATE_GATHER: *state = NVHOST_DBG_STATE_CMD; nvhost_debug_output(o, "%08x]):\n", val); - if (cdma) - show_channel_gather(o, addr, val, *count, cdma); + if (cdma) { + show_channel_gather(o, addr, val, + *count, cdma); + } break; } } @@ -158,6 +167,11 @@ static void show_channel_gather(struct output *o, u32 addr, phys_addr_t pin_addr; int state, count, i; + if ((u32)nvmap->handle == NVHOST_CDMA_PUSH_GATHER_CTXSAVE) { + nvhost_debug_output(o, "[context save]\n"); + return; + } + if (!nvmap->handle || !nvmap->client || atomic_read(&nvmap->handle->ref) < 1) { nvhost_debug_output(o, "[already deallocated]\n"); @@ -285,6 +299,10 @@ static void t20_debug_show_channel_cdma(struct nvhost_master *m, break; } + nvhost_debug_output(o, "DMAPUT %08x, DMAGET %08x, DMACTL %08x\n", + dmaput, dmaget, dmactrl); + nvhost_debug_output(o, "CBREAD %08x, CBSTAT %08x\n", cbread, cbstat); + cdma_peek(cdma, dmaget, -1, pbw); show_channel_pair(o, previous_oppair(cdma, dmaget), pbw[0], pbw[1], &channel->cdma); nvhost_debug_output(o, "\n"); @@ -294,11 +312,17 @@ void t20_debug_show_channel_fifo(struct nvhost_master *m, struct output *o, int chid) { u32 val, rd_ptr, wr_ptr, start, end; + struct nvhost_channel *channel = m->channels + chid; int state, count; - val = readl(m->aperture + HOST1X_CHANNEL_FIFOSTAT); - if (val & (1 << 10)) + nvhost_debug_output(o, "%d: fifo:\n", chid); + + val = readl(channel->aperture + HOST1X_CHANNEL_FIFOSTAT); + nvhost_debug_output(o, "FIFOSTAT %08x\n", val); + if (val & (1 << 10)) { + nvhost_debug_output(o, "[empty]\n"); return; + } writel(0x0, m->aperture + HOST1X_SYNC_CFPEEK_CTRL); writel((1 << 31) | (chid << 16), @@ -313,7 +337,6 @@ void t20_debug_show_channel_fifo(struct nvhost_master *m, end = (val >> 16) & 0x1ff; state = NVHOST_DBG_STATE_CMD; - nvhost_debug_output(o, "%d: fifo:\n", chid); do { writel(0x0, m->aperture + HOST1X_SYNC_CFPEEK_CTRL); diff --git a/drivers/video/tegra/host/t30/3dctx_t30.c b/drivers/video/tegra/host/t30/3dctx_t30.c index 614d079e904e..1678cf91ef4f 100644 --- a/drivers/video/tegra/host/t30/3dctx_t30.c +++ b/drivers/video/tegra/host/t30/3dctx_t30.c @@ -85,6 +85,7 @@ static const struct hwctx_reginfo ctxsave_regs_3d_perset[] = { }; static unsigned int restore_set1_offset; + /* the same context save command sequence is used for all contexts. */ static phys_addr_t save_phys; static unsigned int save_size; @@ -151,8 +152,8 @@ static void save_push_v1(struct nvhost_cdma *cdma, ctx->restore_phys); /* gather the save buffer */ nvhost_cdma_push_gather(cdma, - cdma_to_channel(cdma)->dev->nvmap, - nvmap_ref_to_handle(nvhost_3dctx_save_buf), + (void *)NVHOST_CDMA_PUSH_GATHER_CTXSAVE, + (void *)NVHOST_CDMA_PUSH_GATHER_CTXSAVE, nvhost_opcode_gather(save_size), save_phys); } @@ -272,7 +273,17 @@ static void __init setup_save_regs(struct save_info *info, break; } if (ptr) { - memset(ptr, 0, count * 4); + /* SAVE cases only: reserve room for incoming data */ + u32 k = 0; + /* + * Create a signature pattern for indirect data (which + * will be overwritten by true incoming data) for + * better deducing where we are in a long command + * sequence, when given only a FIFO snapshot for debug + * purposes. + */ + for (k = 0; k < count; k++) + *(ptr + k) = 0xd000d000 | (offset << 16) | k; ptr += count; } save_count += count; @@ -402,8 +413,6 @@ static struct nvhost_hwctx *ctx3d_alloc_v1(struct nvhost_channel *ch) return nvhost_3dctx_alloc_common(ch, false); } -/*** savers ***/ - int __init t30_nvhost_3dctx_handler_init(struct nvhost_hwctx_handler *h) { struct nvhost_channel *ch; -- cgit v1.2.3