diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2013-10-21 14:37:55 +0530 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2013-10-24 01:36:29 -0700 |
commit | ad17341443608b6e3da498acc6177e84a0c320c6 (patch) | |
tree | 13052450361a1b39a7dfafa088513bfb12b57dbc /drivers | |
parent | a790e9b8f4483c7ce00592ec8f2f8b4306146cac (diff) |
video: tegra: host: use virtual address instead of mem_handle
add below functions which support using virtual addresses
instead of mem_handle
_nvhost_cdma_push_gather()
_push_buffer_push_to()
Bug 1380122
Bug 1380147
Change-Id: I6d33eed4d4d254be7f15f839095ad685351db74e
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/301731
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/host/chip_support.h | 3 | ||||
-rw-r--r-- | drivers/video/tegra/host/host1x/host1x_cdma.c | 16 | ||||
-rw-r--r-- | drivers/video/tegra/host/host1x/host1x_hwctx.h | 4 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_cdma.c | 41 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_cdma.h | 4 |
5 files changed, 67 insertions, 1 deletions
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h index ba26401f6bbb..3f015bac8558 100644 --- a/drivers/video/tegra/host/chip_support.h +++ b/drivers/video/tegra/host/chip_support.h @@ -67,6 +67,9 @@ struct nvhost_pushbuffer_ops { void (*push_to)(struct push_buffer *, struct mem_mgr *, struct mem_handle *, u32 op1, u32 op2); + void (*_push_to)(struct push_buffer *, + dma_addr_t iova, + u32 op1, u32 op2); void (*pop_from)(struct push_buffer *, unsigned int slots); u32 (*space)(struct push_buffer *); diff --git a/drivers/video/tegra/host/host1x/host1x_cdma.c b/drivers/video/tegra/host/host1x/host1x_cdma.c index 36d393285b09..4dc6a06f2906 100644 --- a/drivers/video/tegra/host/host1x/host1x_cdma.c +++ b/drivers/video/tegra/host/host1x/host1x_cdma.c @@ -141,6 +141,20 @@ static void push_buffer_push_to(struct push_buffer *pb, pb->cur = (cur + 8) & (PUSH_BUFFER_SIZE - 1); } +static void _push_buffer_push_to(struct push_buffer *pb, + dma_addr_t iova, + u32 op1, u32 op2) +{ + u32 cur = pb->cur; + u32 *p = (u32 *)((uintptr_t)pb->mapped + cur); + u32 cur_nvmap = (cur/8) & (NVHOST_GATHER_QUEUE_SIZE - 1); + WARN_ON(cur == pb->fence); + *(p++) = op1; + *(p++) = op2; + pb->client_handle[cur_nvmap].iova = iova; + pb->cur = (cur + 8) & (PUSH_BUFFER_SIZE - 1); +} + /** * Pop a number of two word slots from the push buffer * Caller must ensure push buffer is not empty @@ -157,6 +171,7 @@ static void push_buffer_pop_from(struct push_buffer *pb, struct mem_mgr_handle *h = &pb->client_handle[cur_fence_nvmap]; h->client = NULL; h->handle = NULL; + h->iova = 0; } /* Advance the next write position */ pb->fence = (pb->fence + slots * 8) & (PUSH_BUFFER_SIZE - 1); @@ -563,6 +578,7 @@ static const struct nvhost_pushbuffer_ops host1x_pushbuffer_ops = { .init = push_buffer_init, .destroy = push_buffer_destroy, .push_to = push_buffer_push_to, + ._push_to = _push_buffer_push_to, .pop_from = push_buffer_pop_from, .space = push_buffer_space, .putptr = push_buffer_putptr, diff --git a/drivers/video/tegra/host/host1x/host1x_hwctx.h b/drivers/video/tegra/host/host1x/host1x_hwctx.h index 0a32026a1b11..8b379902254a 100644 --- a/drivers/video/tegra/host/host1x/host1x_hwctx.h +++ b/drivers/video/tegra/host/host1x/host1x_hwctx.h @@ -3,7 +3,7 @@ * * Tegra Graphics Host HOST1X Hardware Context Interface * - * Copyright (c) 2012-2013, NVIDIA Corporation. + * Copyright (c) 2012-2013, NVIDIA Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,6 +43,8 @@ struct host1x_hwctx { struct sg_table *restore_sgt; dma_addr_t restore_phys; u32 restore_size; + u32 *cpuva; + dma_addr_t iova; }; struct host1x_hwctx_handler { diff --git a/drivers/video/tegra/host/nvhost_cdma.c b/drivers/video/tegra/host/nvhost_cdma.c index 19e8bf13865f..d2adc0e7a83d 100644 --- a/drivers/video/tegra/host/nvhost_cdma.c +++ b/drivers/video/tegra/host/nvhost_cdma.c @@ -455,6 +455,27 @@ static void trace_write_gather(struct nvhost_cdma *cdma, } } +static void _trace_write_gather(struct nvhost_cdma *cdma, + u32 *cpuva, dma_addr_t iova, + u32 offset, u32 words) +{ + if (iova) { + u32 i; + /* + * Write in batches of 128 as there seems to be a limit + * of how much you can output to ftrace at once. + */ + for (i = 0; i < words; i += TRACE_MAX_LENGTH) { + trace_nvhost_cdma_push_gather( + cdma_to_channel(cdma)->dev->name, + (u32)((uintptr_t)iova), + min(words - i, TRACE_MAX_LENGTH), + offset + i * sizeof(u32), + cpuva); + } + } +} + /** * Push two words into a push buffer slot * Blocks as necessary if the push buffer is full. @@ -492,6 +513,26 @@ void nvhost_cdma_push_gather(struct nvhost_cdma *cdma, cdma_pb_op().push_to(pb, client, handle, op1, op2); } +void _nvhost_cdma_push_gather(struct nvhost_cdma *cdma, + u32 *cpuva, dma_addr_t iova, + u32 offset, u32 op1, u32 op2) +{ + u32 slots_free = cdma->slots_free; + struct push_buffer *pb = &cdma->push_buffer; + + if (iova) + _trace_write_gather(cdma, cpuva, iova, offset, op1 & 0x1fff); + + if (slots_free == 0) { + cdma_op().kick(cdma); + slots_free = nvhost_cdma_wait_locked(cdma, + CDMA_EVENT_PUSH_BUFFER_SPACE); + } + cdma->slots_free = slots_free - 1; + cdma->slots_used++; + cdma_pb_op()._push_to(pb, iova, op1, op2); +} + /** * End a cdma submit * Kick off DMA, add job to the sync queue, and a number of slots to be freed diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h index 6bf2524d2dc8..5f5951dca933 100644 --- a/drivers/video/tegra/host/nvhost_cdma.h +++ b/drivers/video/tegra/host/nvhost_cdma.h @@ -50,6 +50,7 @@ struct mem_handle; struct mem_mgr_handle { struct mem_mgr *client; struct mem_handle *handle; + dma_addr_t iova; }; struct push_buffer { @@ -111,6 +112,9 @@ void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2); void nvhost_cdma_push_gather(struct nvhost_cdma *cdma, struct mem_mgr *client, struct mem_handle *handle, u32 offset, u32 op1, u32 op2); +void _nvhost_cdma_push_gather(struct nvhost_cdma *cdma, + u32 *cpuva, dma_addr_t iova, + u32 offset, u32 op1, u32 op2); void nvhost_cdma_end(struct nvhost_cdma *cdma, struct nvhost_job *job); void nvhost_cdma_update(struct nvhost_cdma *cdma); |