]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: host: Add flag for pushing op_done
authorArto Merilainen <amerilainen@nvidia.com>
Tue, 2 Dec 2014 07:48:37 +0000 (09:48 +0200)
committerArto Merilainen <amerilainen@nvidia.com>
Wed, 17 Dec 2014 12:10:15 +0000 (04:10 -0800)
This patch adds flag to mark if kernel should push op_done syncpoint
increment into push buffer.

Bug 200041935
Bug 1576399

Change-Id: I73df9f8a2f4102f522cd3631ebf943bcd84e4c03
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-on: http://git-master/r/660247

drivers/video/tegra/host/bus_client.c
drivers/video/tegra/host/host1x/host1x_channel.c
include/linux/nvhost.h

index 23aaad87f02151f9b06016f69a5bb90577ff5280..6a7dcabbabc4017460fd193c8fc0c616c41d19d2 100644 (file)
@@ -389,6 +389,20 @@ static int nvhost_init_error_notifier(struct nvhost_channel_userctx *ctx,
        return 0;
 }
 
+static inline u32 get_job_fence(struct nvhost_job *job, u32 id)
+{
+       struct nvhost_channel *ch = job->ch;
+       struct nvhost_device_data *pdata = platform_get_drvdata(ch->dev);
+       u32 fence = job->sp[id].fence;
+
+       /* take into account work done increment */
+       if (pdata->push_work_done && id == 0)
+               return fence - 1;
+
+       /* otherwise the fence is valid "as is" */
+       return fence;
+}
+
 static int nvhost_ioctl_channel_submit(struct nvhost_channel_userctx *ctx,
                struct nvhost_submit_args *args)
 {
@@ -554,7 +568,7 @@ static int nvhost_ioctl_channel_submit(struct nvhost_channel_userctx *ctx,
        /* Deliver multiple fences back to the userspace */
        if (fences)
                for (i = 0; i < num_syncpt_incrs; ++i) {
-                       u32 fence = job->sp[i].fence;
+                       u32 fence = get_job_fence(job, i);
                        err = copy_to_user(fences, &fence, sizeof(u32));
                        if (err)
                                break;
@@ -569,7 +583,7 @@ static int nvhost_ioctl_channel_submit(struct nvhost_channel_userctx *ctx,
 
                for (i = 0; i < num_syncpt_incrs; i++) {
                        pts[i].id = job->sp[i].id;
-                       pts[i].thresh = job->sp[i].fence;
+                       pts[i].thresh = get_job_fence(job, i);
                }
 
                err = nvhost_sync_create_fence_fd(ctx->pdev,
@@ -577,7 +591,7 @@ static int nvhost_ioctl_channel_submit(struct nvhost_channel_userctx *ctx,
                if (err)
                        goto fail;
        } else if (num_syncpt_incrs == 1)
-               args->fence = job->sp[job->hwctx_syncpt_idx].fence;
+               args->fence =  get_job_fence(job, job->hwctx_syncpt_idx);
        else
                args->fence = 0;
 
index 59a64532553ec5a277fd1eb216476274d89bc48a..5bdace43d451860cd7cb5f8f784361e3bc7d70b8 100644 (file)
 #include "class_ids.h"
 #include "debug.h"
 
+static void submit_work_done_increment(struct nvhost_job *job)
+{
+       struct nvhost_channel *ch = job->ch;
+       struct nvhost_syncpt *sp = &nvhost_get_host(ch->dev)->syncpt;
+       struct nvhost_device_data *pdata = platform_get_drvdata(ch->dev);
+
+       if (!pdata->push_work_done)
+               return;
+
+       /* make the last increment at job boundary. this will ensure
+        * that the user command buffer is no longer in use */
+       job->sp[0].fence = nvhost_syncpt_incr_max(sp, job->sp[0].id, 1);
+       nvhost_cdma_push(&ch->cdma, nvhost_opcode_imm_incr_syncpt(0,
+                       job->sp[0].id), NVHOST_OPCODE_NOOP);
+}
+
 static void lock_device(struct nvhost_job *job, bool lock)
 {
        struct nvhost_channel *ch = job->ch;
@@ -327,6 +343,7 @@ static int host1x_channel_submit(struct nvhost_job *job)
                submit_gathers(job);
 
        lock_device(job, false);
+       submit_work_done_increment(job);
 
        /* end CDMA submit & stash pinned hMems into sync queue */
        nvhost_cdma_end(&ch->cdma, job);
index a15d6f4abb2754a48f095b34b2c03c9563067852..3c598ce7d6c84986b8b28b6f0c57fcf594ed62e1 100644 (file)
@@ -152,6 +152,7 @@ struct nvhost_device_data {
        bool            exclusive;      /* True if only one user at a time */
        bool            keepalive;      /* Do not power gate when opened */
        bool            serialize;      /* Serialize submits in the channel */
+       bool            push_work_done; /* Push_op done into push buffer */
        bool            poweron_reset;  /* Reset the engine before powerup */
        bool            virtual_dev;    /* True if virtualized device */