summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2011-12-19 15:12:06 +0200
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-22 11:32:23 +0530
commitd993b01464a87a76d0b859e570cb78caaf1996f9 (patch)
tree92b3af033ec92c282f196848d745ec34a9e23d4f /drivers/video
parent204b15d959afb9d3d675c949262ce545c17e7c69 (diff)
video: tegra: host: Move timeout to hwctx & job structs
Timeout struct contains fields which are accessed even after client has quit. Move the fields to hwctx and nvhost_job so that they can be accessed when submits complete. Bug 917340 Change-Id: I322c38d32bc801aa9b061355a17be7f605692e18 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/71004 Reviewed-by: Automatic_Commit_Validation_User Tested-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/tegra/host/3dctx_common.c88
-rw-r--r--drivers/video/tegra/host/chip_support.h1
-rw-r--r--drivers/video/tegra/host/dev.c22
-rw-r--r--drivers/video/tegra/host/dev.h7
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.c73
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.h6
-rw-r--r--drivers/video/tegra/host/nvhost_hwctx.h4
-rw-r--r--drivers/video/tegra/host/nvhost_job.c16
-rw-r--r--drivers/video/tegra/host/nvhost_job.h11
-rw-r--r--drivers/video/tegra/host/t20/cdma_t20.c14
-rw-r--r--drivers/video/tegra/host/t20/channel_t20.c19
-rw-r--r--drivers/video/tegra/host/t20/t20.c14
12 files changed, 86 insertions, 189 deletions
diff --git a/drivers/video/tegra/host/3dctx_common.c b/drivers/video/tegra/host/3dctx_common.c
index a3f38d9127cb..e7673c54e31a 100644
--- a/drivers/video/tegra/host/3dctx_common.c
+++ b/drivers/video/tegra/host/3dctx_common.c
@@ -25,6 +25,7 @@
#include <mach/nvmap.h>
#include <linux/slab.h>
#include "3dctx_common.h"
+#include "t20/t20.h"
#include "t20/hardware_t20.h"
#include "t20/syncpt_t20.h"
#include "nvhost_hwctx.h"
@@ -148,90 +149,5 @@ void nvhost_3dctx_put(struct nvhost_hwctx *ctx)
int nvhost_3dctx_prepare_power_off(struct nvhost_module *mod)
{
- struct nvhost_channel *ch =
- container_of(mod, struct nvhost_channel, mod);
- struct nvhost_hwctx *hwctx_to_save;
- struct nvhost_job *job;
- DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
- u32 syncpt_incrs, syncpt_val;
- int err = 0;
- void *ref;
- void *ctx_waiter = NULL, *wakeup_waiter = NULL;
-
- ctx_waiter = nvhost_intr_alloc_waiter();
- wakeup_waiter = nvhost_intr_alloc_waiter();
- if (!ctx_waiter || !wakeup_waiter) {
- err = -ENOMEM;
- goto done;
- }
- if (mod->desc->busy)
- mod->desc->busy(mod);
-
- mutex_lock(&ch->submitlock);
- hwctx_to_save = ch->cur_ctx;
- if (!hwctx_to_save) {
- mutex_unlock(&ch->submitlock);
- goto done;
- }
-
- job = nvhost_job_alloc(ch, hwctx_to_save,
- NULL,
- ch->dev->nvmap, 0, hwctx_to_save->timeout);
- if (IS_ERR_OR_NULL(job)) {
- err = PTR_ERR(job);
- mutex_unlock(&ch->submitlock);
- goto done;
- }
-
- err = nvhost_cdma_begin(&ch->cdma, hwctx_to_save->timeout);
- if (err) {
- mutex_unlock(&ch->submitlock);
- goto done;
- }
-
- hwctx_to_save->valid = true;
- ch->ctxhandler.get(hwctx_to_save);
- ch->cur_ctx = NULL;
-
- syncpt_incrs = hwctx_to_save->save_incrs;
- syncpt_val = nvhost_syncpt_incr_max(&ch->dev->syncpt,
- NVSYNCPT_3D, syncpt_incrs);
-
- job->syncpt_id = NVSYNCPT_3D;
- job->syncpt_incrs = syncpt_incrs;
- job->syncpt_end = syncpt_val;
-
- ch->ctxhandler.save_push(&ch->cdma, hwctx_to_save);
- nvhost_cdma_end(&ch->cdma, job);
- nvhost_job_put(job);
- job = NULL;
-
- err = nvhost_intr_add_action(&ch->dev->intr, NVSYNCPT_3D,
- syncpt_val - syncpt_incrs + hwctx_to_save->save_thresh,
- NVHOST_INTR_ACTION_CTXSAVE, hwctx_to_save,
- ctx_waiter,
- NULL);
- ctx_waiter = NULL;
- WARN(err, "Failed to set context save interrupt");
-
- err = nvhost_intr_add_action(&ch->dev->intr, NVSYNCPT_3D, syncpt_val,
- NVHOST_INTR_ACTION_WAKEUP, &wq,
- wakeup_waiter,
- &ref);
- wakeup_waiter = NULL;
- WARN(err, "Failed to set wakeup interrupt");
- wait_event(wq,
- nvhost_syncpt_min_cmp(&ch->dev->syncpt,
- NVSYNCPT_3D, syncpt_val));
-
- nvhost_intr_put_ref(&ch->dev->intr, ref);
-
- nvhost_cdma_update(&ch->cdma);
-
- mutex_unlock(&ch->submitlock);
-
-done:
- kfree(ctx_waiter);
- kfree(wakeup_waiter);
- return err;
+ return nvhost_t20_save_context(mod, NVSYNCPT_3D);
}
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h
index d909d34bbe73..3b8c4dc46b45 100644
--- a/drivers/video/tegra/host/chip_support.h
+++ b/drivers/video/tegra/host/chip_support.h
@@ -49,7 +49,6 @@ struct nvhost_chip_support {
int (*submit)(struct nvhost_job *job);
int (*read3dreg)(struct nvhost_channel *channel,
struct nvhost_hwctx *hwctx,
- struct nvhost_userctx_timeout *timeout,
u32 offset,
u32 *value);
} channel;
diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c
index 47d6daa4a482..fe5fb22add92 100644
--- a/drivers/video/tegra/host/dev.c
+++ b/drivers/video/tegra/host/dev.c
@@ -61,8 +61,9 @@ struct nvhost_channel_userctx {
int num_relocshifts;
struct nvhost_job *job;
struct nvmap_client *nvmap;
- struct nvhost_userctx_timeout timeout;
+ u32 timeout;
u32 priority;
+ int clientid;
};
struct nvhost_ctrl_userctx {
@@ -155,13 +156,12 @@ static int nvhost_channelopen(struct inode *inode, struct file *filp)
priv->hwctx = ch->ctxhandler.alloc(ch);
if (!priv->hwctx)
goto fail;
- priv->hwctx->timeout = &priv->timeout;
- priv->timeout.hwctx = priv->hwctx;
}
priv->priority = NVHOST_PRIORITY_MEDIUM;
+ priv->clientid = atomic_add_return(1, &ch->dev->clientid);
priv->job = nvhost_job_alloc(ch, priv->hwctx, &priv->hdr,
- NULL, priv->priority, &priv->timeout);
+ NULL, priv->priority, priv->clientid);
if (!priv->job)
goto fail;
@@ -187,9 +187,11 @@ static int set_submit(struct nvhost_channel_userctx *ctx)
ctx->job = nvhost_job_realloc(ctx->job,
&ctx->hdr,
ctx->nvmap,
- ctx->priority);
+ ctx->priority,
+ ctx->clientid);
if (!ctx->job)
return -ENOMEM;
+ ctx->job->timeout = ctx->timeout;
if (ctx->hdr.submit_version >= NVHOST_SUBMIT_VERSION_V2)
ctx->num_relocshifts = ctx->hdr.num_relocs;
@@ -340,9 +342,8 @@ static int nvhost_ioctl_channel_flush(
if ((nvhost_debug_force_timeout_pid == current->tgid) &&
(nvhost_debug_force_timeout_channel == ctx->ch->chid)) {
- ctx->timeout.timeout = nvhost_debug_force_timeout_val;
+ ctx->timeout = nvhost_debug_force_timeout_val;
}
- ctx->timeout.syncpt_id = ctx->hdr.syncpt_id;
trace_write_cmdbufs(ctx->job);
@@ -361,7 +362,6 @@ static int nvhost_ioctl_channel_read_3d_reg(
{
BUG_ON(!channel_op(ctx->ch).read3dreg);
return channel_op(ctx->ch).read3dreg(ctx->ch, ctx->hwctx,
- &ctx->timeout,
args->offset, &args->value);
}
@@ -480,15 +480,15 @@ static long nvhost_channelctl(struct file *filp,
break;
}
case NVHOST_IOCTL_CHANNEL_SET_TIMEOUT:
- priv->timeout.timeout =
+ priv->timeout =
(u32)((struct nvhost_set_timeout_args *)buf)->timeout;
dev_dbg(&priv->ch->dev->pdev->dev,
"%s: setting buffer timeout (%d ms) for userctx 0x%p\n",
- __func__, priv->timeout.timeout, priv);
+ __func__, priv->timeout, priv);
break;
case NVHOST_IOCTL_CHANNEL_GET_TIMEDOUT:
((struct nvhost_get_param_args *)buf)->value =
- priv->timeout.has_timedout;
+ priv->hwctx->has_timedout;
break;
case NVHOST_IOCTL_CHANNEL_SET_PRIORITY:
priv->priority =
diff --git a/drivers/video/tegra/host/dev.h b/drivers/video/tegra/host/dev.h
index 45217a3ea1a1..3d05da8c53e8 100644
--- a/drivers/video/tegra/host/dev.h
+++ b/drivers/video/tegra/host/dev.h
@@ -54,13 +54,8 @@ struct nvhost_master {
u32 sync_queue_size;
struct nvhost_chip_support op;
-};
-struct nvhost_userctx_timeout {
- u32 timeout;
- bool has_timedout;
- struct nvhost_hwctx *hwctx;
- int syncpt_id;
+ atomic_t clientid;
};
void nvhost_debug_init(struct nvhost_master *master);
diff --git a/drivers/video/tegra/host/nvhost_cdma.c b/drivers/video/tegra/host/nvhost_cdma.c
index efa6a1104ac9..63ce365e990e 100644
--- a/drivers/video/tegra/host/nvhost_cdma.c
+++ b/drivers/video/tegra/host/nvhost_cdma.c
@@ -137,23 +137,23 @@ unsigned int nvhost_cdma_wait_locked(struct nvhost_cdma *cdma,
* Start timer for a buffer submition that has completed yet.
* Must be called with the cdma lock held.
*/
-static void cdma_start_timer_locked(struct nvhost_cdma *cdma, u32 syncpt_id,
- u32 syncpt_val,
- struct nvhost_userctx_timeout *timeout)
+static void cdma_start_timer_locked(struct nvhost_cdma *cdma,
+ struct nvhost_job *job)
{
- BUG_ON(!timeout);
- if (cdma->timeout.ctx_timeout) {
+ BUG_ON(!job);
+ if (cdma->timeout.clientid) {
/* timer already started */
return;
}
- cdma->timeout.ctx_timeout = timeout;
- cdma->timeout.syncpt_id = syncpt_id;
- cdma->timeout.syncpt_val = syncpt_val;
+ cdma->timeout.ctx = job->hwctx;
+ cdma->timeout.clientid = job->clientid;
+ cdma->timeout.syncpt_id = job->syncpt_id;
+ cdma->timeout.syncpt_val = job->syncpt_end;
cdma->timeout.start_ktime = ktime_get();
schedule_delayed_work(&cdma->timeout.wq,
- msecs_to_jiffies(timeout->timeout));
+ msecs_to_jiffies(job->timeout));
}
/**
@@ -163,7 +163,8 @@ static void cdma_start_timer_locked(struct nvhost_cdma *cdma, u32 syncpt_id,
static void stop_cdma_timer_locked(struct nvhost_cdma *cdma)
{
cancel_delayed_work(&cdma->timeout.wq);
- cdma->timeout.ctx_timeout = NULL;
+ cdma->timeout.ctx = NULL;
+ cdma->timeout.clientid = 0;
}
/**
@@ -205,15 +206,13 @@ static void update_cdma_locked(struct nvhost_cdma *cdma)
if (!nvhost_syncpt_min_cmp(sp,
job->syncpt_id, job->syncpt_end)) {
/* Start timer on next pending syncpt */
- if (job->timeout->timeout) {
- cdma_start_timer_locked(cdma, job->syncpt_id,
- job->syncpt_end, job->timeout);
- }
+ if (job->timeout)
+ cdma_start_timer_locked(cdma, job);
break;
}
/* Cancel timeout, when a buffer completes */
- if (cdma->timeout.ctx_timeout)
+ if (cdma->timeout.clientid)
stop_cdma_timer_locked(cdma);
/* Unpin the memory */
@@ -302,13 +301,13 @@ void nvhost_cdma_update_sync_queue(struct nvhost_cdma *cdma,
get_restart = job->first_get;
/* do CPU increments as long as this context continues */
- while (result && job->timeout == cdma->timeout.ctx_timeout) {
+ while (result && job->clientid == cdma->timeout.clientid) {
/* different context, gets us out of this loop */
- if (job->timeout != cdma->timeout.ctx_timeout)
+ if (job->clientid != cdma->timeout.clientid)
break;
/* won't need a timeout when replayed */
- job->timeout->timeout = 0;
+ job->timeout = 0;
syncpt_incrs = job->syncpt_end - syncpt_val;
dev_dbg(dev,
@@ -336,9 +335,9 @@ void nvhost_cdma_update_sync_queue(struct nvhost_cdma *cdma,
/* setup GPU increments */
while (result) {
/* same context, increment in the pushbuffer */
- if (job->timeout == cdma->timeout.ctx_timeout) {
+ if (job->clientid == cdma->timeout.clientid) {
/* won't need a timeout when replayed */
- job->timeout->timeout = 0;
+ job->timeout = 0;
/* update buffer's syncpts in the pushbuffer */
cdma_op(cdma).timeout_pb_incr(cdma,
@@ -349,7 +348,7 @@ void nvhost_cdma_update_sync_queue(struct nvhost_cdma *cdma,
exec_ctxsave = false;
} else {
- dev_warn(dev,
+ dev_dbg(dev,
"%s: switch to a different userctx\n",
__func__);
/*
@@ -373,7 +372,8 @@ void nvhost_cdma_update_sync_queue(struct nvhost_cdma *cdma,
/* roll back DMAGET and start up channel again */
cdma_op(cdma).timeout_teardown_end(cdma, get_restart);
- cdma->timeout.ctx_timeout->has_timedout = true;
+ if (cdma->timeout.ctx)
+ cdma->timeout.ctx->has_timedout = true;
}
/**
@@ -421,33 +421,17 @@ void nvhost_cdma_deinit(struct nvhost_cdma *cdma)
/**
* Begin a cdma submit
*/
-int nvhost_cdma_begin(struct nvhost_cdma *cdma,
- struct nvhost_userctx_timeout *timeout)
+int nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_job *job)
{
mutex_lock(&cdma->lock);
- if (timeout && timeout->has_timedout) {
- struct nvhost_master *dev = cdma_to_dev(cdma);
- u32 min, max;
-
- min = nvhost_syncpt_update_min(&dev->syncpt,
- cdma->timeout.syncpt_id);
- max = nvhost_syncpt_read_min(&dev->syncpt,
- cdma->timeout.syncpt_id);
-
- dev_dbg(&dev->pdev->dev,
- "%s: skip timed out ctx submit (min = %d, max = %d)\n",
- __func__, min, max);
- mutex_unlock(&cdma->lock);
- return -ETIMEDOUT;
- }
- if (timeout->timeout) {
+ if (job->timeout) {
/* init state on first submit with timeout value */
if (!cdma->timeout.initialized) {
int err;
BUG_ON(!cdma_op(cdma).timeout_init);
err = cdma_op(cdma).timeout_init(cdma,
- timeout->syncpt_id);
+ job->syncpt_id);
if (err) {
mutex_unlock(&cdma->lock);
return err;
@@ -520,11 +504,8 @@ void nvhost_cdma_end(struct nvhost_cdma *cdma,
cdma->first_get);
/* start timer on idle -> active transitions */
- if (job->timeout->timeout && was_idle) {
- cdma_start_timer_locked(cdma,
- job->syncpt_id, job->syncpt_end,
- job->timeout);
- }
+ if (job->timeout && was_idle)
+ cdma_start_timer_locked(cdma, job);
mutex_unlock(&cdma->lock);
}
diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h
index c8c9e168b833..87b6a14d60e3 100644
--- a/drivers/video/tegra/host/nvhost_cdma.h
+++ b/drivers/video/tegra/host/nvhost_cdma.h
@@ -80,7 +80,8 @@ struct buffer_timeout {
u32 syncpt_val; /* syncpt value when completed */
ktime_t start_ktime; /* starting time */
/* context timeout information */
- struct nvhost_userctx_timeout *ctx_timeout;
+ struct nvhost_hwctx *ctx;
+ int clientid;
};
enum cdma_event {
@@ -116,8 +117,7 @@ struct nvhost_cdma {
int nvhost_cdma_init(struct nvhost_cdma *cdma);
void nvhost_cdma_deinit(struct nvhost_cdma *cdma);
void nvhost_cdma_stop(struct nvhost_cdma *cdma);
-int nvhost_cdma_begin(struct nvhost_cdma *cdma,
- struct nvhost_userctx_timeout *timeout);
+int nvhost_cdma_begin(struct nvhost_cdma *cdma, struct nvhost_job *job);
void nvhost_cdma_push(struct nvhost_cdma *cdma, u32 op1, u32 op2);
#define NVHOST_CDMA_PUSH_GATHER_CTXSAVE 0xffffffff
void nvhost_cdma_push_gather(struct nvhost_cdma *cdma,
diff --git a/drivers/video/tegra/host/nvhost_hwctx.h b/drivers/video/tegra/host/nvhost_hwctx.h
index 6d6f458d7d75..9fbab78c8331 100644
--- a/drivers/video/tegra/host/nvhost_hwctx.h
+++ b/drivers/video/tegra/host/nvhost_hwctx.h
@@ -31,13 +31,11 @@
struct nvhost_channel;
struct nvhost_cdma;
-struct nvhost_userctx_timeout;
struct nvhost_hwctx {
struct kref ref;
struct nvhost_channel *channel;
- struct nvhost_userctx_timeout *timeout;
bool valid;
struct nvmap_handle_ref *save;
@@ -50,6 +48,8 @@ struct nvhost_hwctx {
phys_addr_t restore_phys;
u32 restore_size;
u32 restore_incrs;
+
+ bool has_timedout;
};
struct nvhost_hwctx_handler {
diff --git a/drivers/video/tegra/host/nvhost_job.c b/drivers/video/tegra/host/nvhost_job.c
index ac9c5fefa083..d0c5d731f615 100644
--- a/drivers/video/tegra/host/nvhost_job.c
+++ b/drivers/video/tegra/host/nvhost_job.c
@@ -121,7 +121,7 @@ static int realloc_gathers(struct nvhost_job *oldjob,
static void init_fields(struct nvhost_job *job,
struct nvhost_submit_hdr_ext *hdr,
- int priority)
+ int priority, int clientid)
{
int num_pins = hdr ? (hdr->num_relocs + hdr->num_cmdbufs)*2 : 0;
int num_waitchks = hdr ? hdr->num_waitchks : 0;
@@ -137,6 +137,7 @@ static void init_fields(struct nvhost_job *job,
job->syncpt_incrs = 0;
job->syncpt_end = 0;
job->priority = priority;
+ job->clientid = clientid;
job->null_kickoff = false;
job->first_get = 0;
job->num_slots = 0;
@@ -168,7 +169,7 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch,
struct nvhost_submit_hdr_ext *hdr,
struct nvmap_client *nvmap,
int priority,
- struct nvhost_userctx_timeout *timeout)
+ int clientid)
{
struct nvhost_job *job = NULL;
int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0;
@@ -181,14 +182,13 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch,
kref_init(&job->ref);
job->ch = ch;
job->hwctx = hwctx;
- job->timeout = timeout;
job->nvmap = nvmap ? nvmap_client_get(nvmap) : NULL;
err = alloc_gathers(job, num_cmdbufs);
if (err)
goto error;
- init_fields(job, hdr, priority);
+ init_fields(job, hdr, priority, clientid);
return job;
@@ -202,7 +202,7 @@ struct nvhost_job *nvhost_job_realloc(
struct nvhost_job *oldjob,
struct nvhost_submit_hdr_ext *hdr,
struct nvmap_client *nvmap,
- int priority)
+ int priority, int clientid)
{
struct nvhost_job *newjob = NULL;
int num_cmdbufs = hdr ? hdr->num_cmdbufs : 0;
@@ -223,7 +223,7 @@ struct nvhost_job *nvhost_job_realloc(
nvhost_job_put(oldjob);
- init_fields(newjob, hdr, priority);
+ init_fields(newjob, hdr, priority, clientid);
return newjob;
@@ -311,9 +311,9 @@ void nvhost_job_dump(struct device *dev, struct nvhost_job *job)
dev_dbg(dev, " FIRST_GET 0x%x\n",
job->first_get);
dev_dbg(dev, " TIMEOUT %d\n",
- job->timeout->timeout);
- dev_dbg(dev, " TIMEOUT_CTX 0x%p\n",
job->timeout);
+ dev_dbg(dev, " CTX 0x%p\n",
+ job->hwctx);
dev_dbg(dev, " NUM_SLOTS %d\n",
job->num_slots);
dev_dbg(dev, " NUM_HANDLES %d\n",
diff --git a/drivers/video/tegra/host/nvhost_job.h b/drivers/video/tegra/host/nvhost_job.h
index 42e1c46d4525..d00d60f2164a 100644
--- a/drivers/video/tegra/host/nvhost_job.h
+++ b/drivers/video/tegra/host/nvhost_job.h
@@ -30,7 +30,6 @@ struct nvhost_hwctx;
struct nvmap_client;
struct nvhost_waitchk;
struct nvmap_handle;
-struct nvhost_userctx_timeout;
/*
* Each submit is tracked as a nvhost_job.
@@ -44,7 +43,7 @@ struct nvhost_job {
/* Hardware context valid for this client */
struct nvhost_hwctx *hwctx;
- struct nvhost_userctx_timeout *timeout;
+ int clientid;
/* Nvmap to be used for pinning & unpinning memory */
struct nvmap_client *nvmap;
@@ -74,6 +73,9 @@ struct nvhost_job {
/* Priority of this submit. */
int priority;
+ /* Maximum time to wait for this job */
+ int timeout;
+
/* Null kickoff prevents submit from being sent to hardware */
bool null_kickoff;
@@ -90,8 +92,7 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch,
struct nvhost_hwctx *hwctx,
struct nvhost_submit_hdr_ext *hdr,
struct nvmap_client *nvmap,
- int priority,
- struct nvhost_userctx_timeout *timeout);
+ int priority, int clientid);
/*
* Allocate memory for a job. Just enough memory will be allocated to
@@ -101,7 +102,7 @@ struct nvhost_job *nvhost_job_alloc(struct nvhost_channel *ch,
struct nvhost_job *nvhost_job_realloc(struct nvhost_job *oldjob,
struct nvhost_submit_hdr_ext *hdr,
struct nvmap_client *nvmap,
- int priority);
+ int priority, int clientid);
/*
* Add a gather to a job.
diff --git a/drivers/video/tegra/host/t20/cdma_t20.c b/drivers/video/tegra/host/t20/cdma_t20.c
index fc2afdb26189..c034bdf90bbc 100644
--- a/drivers/video/tegra/host/t20/cdma_t20.c
+++ b/drivers/video/tegra/host/t20/cdma_t20.c
@@ -328,7 +328,7 @@ static void t20_cdma_timeout_pb_incr(struct nvhost_cdma *cdma, u32 getptr,
struct nvhost_master *dev = cdma_to_dev(cdma);
struct syncpt_buffer *sb = &cdma->syncpt_buffer;
struct push_buffer *pb = &cdma->push_buffer;
- struct nvhost_userctx_timeout *timeout = cdma->timeout.ctx_timeout;
+ struct nvhost_hwctx *hwctx = cdma->timeout.ctx;
u32 getidx, *p;
/* should have enough slots to incr to desired count */
@@ -337,10 +337,10 @@ static void t20_cdma_timeout_pb_incr(struct nvhost_cdma *cdma, u32 getptr,
getidx = getptr - pb->phys;
if (exec_ctxsave) {
/* don't disrupt the CTXSAVE of a good/non-timed out ctx */
- nr_slots -= timeout->hwctx->save_slots;
- syncpt_incrs -= timeout->hwctx->save_incrs;
+ nr_slots -= hwctx->save_slots;
+ syncpt_incrs -= hwctx->save_incrs;
- getidx += (timeout->hwctx->save_slots * 8);
+ getidx += (hwctx->save_slots * 8);
getidx &= (PUSH_BUFFER_SIZE - 1);
dev_dbg(&dev->pdev->dev,
@@ -587,9 +587,9 @@ static void t20_cdma_timeout_handler(struct work_struct *work)
mutex_lock(&cdma->lock);
- if (!cdma->timeout.ctx_timeout) {
+ if (!cdma->timeout.clientid) {
dev_dbg(&dev->pdev->dev,
- "cdma_timeout: expired, but has NULL context\n");
+ "cdma_timeout: expired, but has no clientid\n");
mutex_unlock(&cdma->lock);
return;
}
@@ -623,7 +623,7 @@ static void t20_cdma_timeout_handler(struct work_struct *work)
__func__,
cdma->timeout.syncpt_id,
syncpt_op(sp).name(sp, cdma->timeout.syncpt_id),
- cdma->timeout.ctx_timeout,
+ cdma->timeout.ctx,
syncpt_val, cdma->timeout.syncpt_val);
/* stop HW, resetting channel/module */
diff --git a/drivers/video/tegra/host/t20/channel_t20.c b/drivers/video/tegra/host/t20/channel_t20.c
index 132bdb526bbc..6f5b1f51f11a 100644
--- a/drivers/video/tegra/host/t20/channel_t20.c
+++ b/drivers/video/tegra/host/t20/channel_t20.c
@@ -201,6 +201,9 @@ static int t20_channel_submit(struct nvhost_job *job)
void *ctxrestore_waiter = NULL;
void *ctxsave_waiter, *completed_waiter;
+ if (job->hwctx && job->hwctx->has_timedout)
+ return -ETIMEDOUT;
+
ctxsave_waiter = nvhost_intr_alloc_waiter();
completed_waiter = nvhost_intr_alloc_waiter();
if (!ctxsave_waiter || !completed_waiter) {
@@ -252,7 +255,7 @@ static int t20_channel_submit(struct nvhost_job *job)
}
/* begin a CDMA submit */
- err = nvhost_cdma_begin(&channel->cdma, job->timeout);
+ err = nvhost_cdma_begin(&channel->cdma, job);
if (err) {
mutex_unlock(&channel->submitlock);
nvhost_module_idle(&channel->mod);
@@ -266,12 +269,12 @@ static int t20_channel_submit(struct nvhost_job *job)
trace_nvhost_channel_context_switch(channel->desc->name,
channel->cur_ctx, job->hwctx);
hwctx_to_save = channel->cur_ctx;
- if (hwctx_to_save && hwctx_to_save->timeout &&
- hwctx_to_save->timeout->has_timedout) {
+ if (hwctx_to_save &&
+ hwctx_to_save->has_timedout) {
hwctx_to_save = NULL;
dev_dbg(&channel->dev->pdev->dev,
"%s: skip save of timed out context (0x%p)\n",
- __func__, channel->cur_ctx->timeout);
+ __func__, channel->cur_ctx);
}
if (hwctx_to_save) {
job->syncpt_incrs += hwctx_to_save->save_incrs;
@@ -404,7 +407,6 @@ done:
static int t20_channel_read_3d_reg(
struct nvhost_channel *channel,
struct nvhost_hwctx *hwctx,
- struct nvhost_userctx_timeout *timeout,
u32 offset,
u32 *value)
{
@@ -419,6 +421,9 @@ static int t20_channel_read_3d_reg(
u32 syncval;
int err;
+ if (hwctx && hwctx->has_timedout)
+ return -ETIMEDOUT;
+
ctx_waiter = nvhost_intr_alloc_waiter();
read_waiter = nvhost_intr_alloc_waiter();
completed_waiter = nvhost_intr_alloc_waiter();
@@ -429,7 +434,7 @@ static int t20_channel_read_3d_reg(
job = nvhost_job_alloc(channel, hwctx,
NULL,
- channel->dev->nvmap, 0, timeout);
+ channel->dev->nvmap, 0, 0);
if (!job) {
err = -ENOMEM;
goto done;
@@ -468,7 +473,7 @@ static int t20_channel_read_3d_reg(
job->syncpt_end = syncval;
/* begin a CDMA submit */
- nvhost_cdma_begin(&channel->cdma, timeout);
+ nvhost_cdma_begin(&channel->cdma, job);
/* push save buffer (pre-gather setup depends on unit) */
if (hwctx_to_save)
diff --git a/drivers/video/tegra/host/t20/t20.c b/drivers/video/tegra/host/t20/t20.c
index 605f4edf015f..e523c27a0fb0 100644
--- a/drivers/video/tegra/host/t20/t20.c
+++ b/drivers/video/tegra/host/t20/t20.c
@@ -95,19 +95,13 @@ int nvhost_t20_save_context(struct nvhost_module *mod, u32 syncpt_id)
job = nvhost_job_alloc(ch, hwctx_to_save,
NULL,
- ch->dev->nvmap, 0, hwctx_to_save->timeout);
+ ch->dev->nvmap, 0, 0);
if (IS_ERR_OR_NULL(job)) {
err = PTR_ERR(job);
mutex_unlock(&ch->submitlock);
goto done;
}
- err = nvhost_cdma_begin(&ch->cdma, hwctx_to_save->timeout);
- if (err) {
- mutex_unlock(&ch->submitlock);
- goto done;
- }
-
hwctx_to_save->valid = true;
ch->ctxhandler.get(hwctx_to_save);
ch->cur_ctx = NULL;
@@ -120,6 +114,12 @@ int nvhost_t20_save_context(struct nvhost_module *mod, u32 syncpt_id)
job->syncpt_incrs = syncpt_incrs;
job->syncpt_end = syncpt_val;
+ err = nvhost_cdma_begin(&ch->cdma, job);
+ if (err) {
+ mutex_unlock(&ch->submitlock);
+ goto done;
+ }
+
ch->ctxhandler.save_push(&ch->cdma, hwctx_to_save);
nvhost_cdma_end(&ch->cdma, job);
nvhost_job_put(job);