diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2011-08-17 14:36:51 +0300 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-10-06 16:59:51 -0700 |
commit | 1b12dbd994338535fd45501243c791659f09cdcd (patch) | |
tree | ca50f14830cb6edb1806bd53c3ad51a77186b687 /drivers | |
parent | 334cfb4331ab5d7252863b2fa9d2e2ae4ce3f6b6 (diff) |
tegra: nvhost: Retrieve phys address from nvmap
Debug code used to rely on being able to calculate the base address of a
pinned page by masking it. Now we always retrieve the physical address
from nvmap and find the correct command buffer using that.
Bug 840976
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/48105
Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
(cherry picked from commit 0ef5f2d4d94464b8d5562327c9cf5b56fe93fff5)
Change-Id: I1a17665cf19d8758f154d4fd05f6a5ec6c07caff
Reviewed-on: http://git-master/r/56266
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/host/chip_support.h | 1 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_cdma.c | 5 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_cdma.h | 8 | ||||
-rw-r--r-- | drivers/video/tegra/host/t20/3dctx_t20.c | 1 | ||||
-rw-r--r-- | drivers/video/tegra/host/t20/cdma_t20.c | 20 | ||||
-rw-r--r-- | drivers/video/tegra/host/t20/channel_t20.c | 2 | ||||
-rw-r--r-- | drivers/video/tegra/host/t20/debug_t20.c | 17 | ||||
-rw-r--r-- | drivers/video/tegra/host/t30/3dctx_t30.c | 4 |
8 files changed, 38 insertions, 20 deletions
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h index cdd26fa8147f..1b141798c157 100644 --- a/drivers/video/tegra/host/chip_support.h +++ b/drivers/video/tegra/host/chip_support.h @@ -93,6 +93,7 @@ struct nvhost_chip_support { int (*init)(struct push_buffer *); void (*destroy)(struct push_buffer *); void (*push_to)(struct push_buffer *, + struct nvmap_client *, struct nvmap_handle *, u32 op1, u32 op2); void (*pop_from)(struct push_buffer *, diff --git a/drivers/video/tegra/host/nvhost_cdma.c b/drivers/video/tegra/host/nvhost_cdma.c index b125f76414cc..5c04e5838d2a 100644 --- a/drivers/video/tegra/host/nvhost_cdma.c +++ b/drivers/video/tegra/host/nvhost_cdma.c @@ -691,7 +691,7 @@ int nvhost_cdma_begin(struct nvhost_cdma *cdma, */ void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2) { - nvhost_cdma_push_gather(cdma, NULL, op1, op2); + nvhost_cdma_push_gather(cdma, NULL, NULL, op1, op2); } /** @@ -699,6 +699,7 @@ void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2) * Blocks as necessary if the push buffer is full. */ void nvhost_cdma_push_gather(struct nvhost_cdma *cdma, + struct nvmap_client *client, struct nvmap_handle *handle, u32 op1, u32 op2) { u32 slots_free = cdma->slots_free; @@ -712,7 +713,7 @@ void nvhost_cdma_push_gather(struct nvhost_cdma *cdma, } cdma->slots_free = slots_free - 1; cdma->slots_used++; - cdma_pb_op(cdma).push_to(pb, handle, op1, op2); + cdma_pb_op(cdma).push_to(pb, client, handle, op1, op2); } /** diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h index 8bdc18b90220..e5e1d5f88701 100644 --- a/drivers/video/tegra/host/nvhost_cdma.h +++ b/drivers/video/tegra/host/nvhost_cdma.h @@ -48,6 +48,10 @@ struct nvhost_userctx_timeout; * update - call to update sync queue and push buffer, unpin memory */ +struct nvmap_client_handle { + struct nvmap_client *client; + struct nvmap_handle *handle; +}; struct push_buffer { struct nvmap_handle_ref *mem; /* handle to pushbuffer memory */ @@ -55,7 +59,8 @@ struct push_buffer { u32 phys; /* physical address of pushbuffer */ u32 fence; /* index we've written */ u32 cur; /* index to write to */ - struct nvmap_handle **handles; /* nvmap handle for each opcode pair */ + struct nvmap_client_handle *nvmap; + /* nvmap handle for each opcode pair */ }; struct syncpt_buffer { @@ -131,6 +136,7 @@ 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); void nvhost_cdma_push_gather(struct nvhost_cdma *cdma, + struct nvmap_client *client, struct nvmap_handle *handle, u32 op1, u32 op2); void nvhost_cdma_end(struct nvhost_cdma *cdma, struct nvmap_client *user_nvmap, diff --git a/drivers/video/tegra/host/t20/3dctx_t20.c b/drivers/video/tegra/host/t20/3dctx_t20.c index ebf6c73d2693..7ac1b5e118cd 100644 --- a/drivers/video/tegra/host/t20/3dctx_t20.c +++ b/drivers/video/tegra/host/t20/3dctx_t20.c @@ -138,6 +138,7 @@ 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), nvhost_opcode_gather(save_size), save_phys); diff --git a/drivers/video/tegra/host/t20/cdma_t20.c b/drivers/video/tegra/host/t20/cdma_t20.c index 130cf08e8c6c..98b9e1dd0040 100644 --- a/drivers/video/tegra/host/t20/cdma_t20.c +++ b/drivers/video/tegra/host/t20/cdma_t20.c @@ -57,7 +57,7 @@ static int t20_push_buffer_init(struct push_buffer *pb) pb->mem = NULL; pb->mapped = NULL; pb->phys = 0; - pb->handles = NULL; + pb->nvmap = NULL; BUG_ON(!cdma_pb_op(cdma).reset); cdma_pb_op(cdma).reset(pb); @@ -80,9 +80,11 @@ static int t20_push_buffer_init(struct push_buffer *pb) goto fail; } - /* memory for storing nvmap handles for each opcode pair */ - pb->handles = kzalloc(PUSH_BUFFER_SIZE/2, GFP_KERNEL); - if (!pb->handles) + /* memory for storing nvmap client and handles for each opcode pair */ + pb->nvmap = kzalloc(PUSH_BUFFER_SIZE/2 * + sizeof(struct nvmap_client_handle), + GFP_KERNEL); + if (!pb->nvmap) goto fail; /* put the restart at the end of pushbuffer memory */ @@ -111,12 +113,12 @@ static void t20_push_buffer_destroy(struct push_buffer *pb) if (pb->mem) nvmap_free(nvmap, pb->mem); - kfree(pb->handles); + kfree(pb->nvmap); pb->mem = NULL; pb->mapped = NULL; pb->phys = 0; - pb->handles = 0; + pb->nvmap = 0; } /** @@ -124,14 +126,16 @@ static void t20_push_buffer_destroy(struct push_buffer *pb) * Caller must ensure push buffer is not full */ static void t20_push_buffer_push_to(struct push_buffer *pb, - struct nvmap_handle *handle, u32 op1, u32 op2) + struct nvmap_client *client, + struct nvmap_handle *handle, u32 op1, u32 op2) { u32 cur = pb->cur; u32 *p = (u32 *)((u32)pb->mapped + cur); BUG_ON(cur == pb->fence); *(p++) = op1; *(p++) = op2; - pb->handles[cur/8] = handle; + pb->nvmap[cur/8].client = client; + pb->nvmap[cur/8].handle = handle; pb->cur = (cur + 8) & (PUSH_BUFFER_SIZE - 1); /* printk("push_to_push_buffer: op1=%08x; op2=%08x; cur=%x\n", op1, op2, pb->cur); */ } diff --git a/drivers/video/tegra/host/t20/channel_t20.c b/drivers/video/tegra/host/t20/channel_t20.c index d1c0b1f72066..e446034a7cb4 100644 --- a/drivers/video/tegra/host/t20/channel_t20.c +++ b/drivers/video/tegra/host/t20/channel_t20.c @@ -239,6 +239,7 @@ static int t20_channel_submit(struct nvhost_channel *channel, /* gather restore buffer */ if (need_restore) nvhost_cdma_push_gather(&channel->cdma, + channel->dev->nvmap, nvmap_ref_to_handle(channel->cur_ctx->restore), nvhost_opcode_gather(channel->cur_ctx->restore_size), channel->cur_ctx->restore_phys); @@ -278,6 +279,7 @@ static int t20_channel_submit(struct nvhost_channel *channel, int i = 0; for ( ; i < gather_end-gather; i += 2) { nvhost_cdma_push_gather(&channel->cdma, + user_nvmap, unpins[i/2], nvhost_opcode_gather(gather[i]), gather[i+1]); diff --git a/drivers/video/tegra/host/t20/debug_t20.c b/drivers/video/tegra/host/t20/debug_t20.c index fb101230cd8b..ed4a5e1de21c 100644 --- a/drivers/video/tegra/host/t20/debug_t20.c +++ b/drivers/video/tegra/host/t20/debug_t20.c @@ -146,32 +146,33 @@ static void show_channel_gather(struct output *o, u32 addr, phys_addr_t phys_addr, u32 words, struct nvhost_cdma *cdma) { - /* Calculate page boundary and offset */ - phys_addr_t map_base = phys_addr & PAGE_MASK; - phys_addr_t map_offset = phys_addr - map_base; - /* Map dmaget cursor to corresponding nvmap_handle */ struct push_buffer *pb = &cdma->push_buffer; u32 cur = addr - pb->phys; - struct nvmap_handle *h = pb->handles[cur/8]; + struct nvmap_client_handle *nvmap = &pb->nvmap[cur/8]; /* Create a fake nvmap_handle_ref - nvmap_mmap requires it * but accesses only the first field - nvmap_handle */ - struct nvmap_handle_ref ref = {.handle = h}; + struct nvmap_handle_ref ref = {.handle = nvmap->handle}; - u32 *map_addr; + u32 *map_addr, pin_addr, offset; int state, count, i; map_addr = nvmap_mmap(&ref); if (!map_addr) return; + /* Get base address from nvmap */ + pin_addr = nvmap_pin(nvmap->client, &ref); + offset = phys_addr - pin_addr; + nvmap_unpin(nvmap->client, &ref); + /* GATHER buffer starts always with commands */ state = NVHOST_DBG_STATE_CMD; for (i = 0; i < words; i++) show_channel_word(o, &state, &count, phys_addr + i * 4, - *(map_addr + map_offset/4 + i), cdma); + *(map_addr + offset/4 + i), cdma); nvmap_munmap(&ref, map_addr); } diff --git a/drivers/video/tegra/host/t30/3dctx_t30.c b/drivers/video/tegra/host/t30/3dctx_t30.c index 264e7c144285..614d079e904e 100644 --- a/drivers/video/tegra/host/t30/3dctx_t30.c +++ b/drivers/video/tegra/host/t30/3dctx_t30.c @@ -150,7 +150,9 @@ static void save_push_v1(struct nvhost_cdma *cdma, nvhost_opcode_nonincr(0x904, 1), ctx->restore_phys); /* gather the save buffer */ - nvhost_cdma_push(cdma, + nvhost_cdma_push_gather(cdma, + cdma_to_channel(cdma)->dev->nvmap, + nvmap_ref_to_handle(nvhost_3dctx_save_buf), nvhost_opcode_gather(save_size), save_phys); } |