]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: host: use virtual address instead of mem_handle
authorDeepak Nibade <dnibade@nvidia.com>
Mon, 21 Oct 2013 09:07:55 +0000 (14:37 +0530)
committerTerje Bergstrom <tbergstrom@nvidia.com>
Thu, 24 Oct 2013 08:36:29 +0000 (01:36 -0700)
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>
drivers/video/tegra/host/chip_support.h
drivers/video/tegra/host/host1x/host1x_cdma.c
drivers/video/tegra/host/host1x/host1x_hwctx.h
drivers/video/tegra/host/nvhost_cdma.c
drivers/video/tegra/host/nvhost_cdma.h

index ba26401f6bbb9df82defe297c430cd497a6e4a07..3f015bac8558330a1b6adc5ff8391200eb868fba 100644 (file)
@@ -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 *);
index 36d393285b09fd5ea716d18b4c9c6e7c7c772102..4dc6a06f29061aa1cefb0bda771ab1b43c2b71eb 100644 (file)
@@ -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,
index 0a32026a1b116e86385efe1b77442d20b96c11ef..8b379902254a925dfcaf9694224f7e2853616379 100644 (file)
@@ -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 {
index 19e8bf13865fd35b8220c26bb5b335dd77592fda..d2adc0e7a83de685c39d875f6e0b487aba730703 100644 (file)
@@ -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
index 6bf2524d2dc8f95157c5c55aca0222b7f3a04007..5f5951dca933b21d3172dfe908b73d901f5242fb 100644 (file)
@@ -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);