summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2013-10-21 14:37:55 +0530
committerTerje Bergstrom <tbergstrom@nvidia.com>2013-10-24 01:36:29 -0700
commitad17341443608b6e3da498acc6177e84a0c320c6 (patch)
tree13052450361a1b39a7dfafa088513bfb12b57dbc /drivers
parenta790e9b8f4483c7ce00592ec8f2f8b4306146cac (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.h3
-rw-r--r--drivers/video/tegra/host/host1x/host1x_cdma.c16
-rw-r--r--drivers/video/tegra/host/host1x/host1x_hwctx.h4
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.c41
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.h4
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);