summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/host/bus_client.c6
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.c33
-rw-r--r--drivers/video/tegra/host/nvhost_cdma.h3
-rw-r--r--drivers/video/tegra/host/nvhost_channel.c24
-rw-r--r--drivers/video/tegra/host/nvhost_intr.c10
5 files changed, 63 insertions, 13 deletions
diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c
index 9b71542a48aa..87aa9c64d363 100644
--- a/drivers/video/tegra/host/bus_client.c
+++ b/drivers/video/tegra/host/bus_client.c
@@ -141,12 +141,6 @@ static int nvhost_channelopen(struct inode *inode, struct file *filp)
priv->clientid = atomic_add_return(1,
&nvhost_get_host(ch->dev)->clientid);
priv->timeout = MAX_STUCK_CHECK_COUNT * SYNCPT_CHECK_PERIOD;
-
- priv->job = nvhost_job_alloc(ch, priv->hwctx, &priv->hdr,
- NULL, priv->priority, priv->clientid);
- if (!priv->job)
- goto fail;
-
return 0;
fail:
nvhost_channelrelease(inode, filp);
diff --git a/drivers/video/tegra/host/nvhost_cdma.c b/drivers/video/tegra/host/nvhost_cdma.c
index b1f138317cc1..c87415bf5ac2 100644
--- a/drivers/video/tegra/host/nvhost_cdma.c
+++ b/drivers/video/tegra/host/nvhost_cdma.c
@@ -53,6 +53,18 @@ static void add_to_sync_queue(struct nvhost_cdma *cdma,
job->num_slots = nr_slots;
nvhost_job_get(job);
list_add_tail(&job->list, &cdma->sync_queue);
+
+ switch (job->priority) {
+ case NVHOST_PRIORITY_HIGH:
+ cdma->high_prio_count++;
+ break;
+ case NVHOST_PRIORITY_MEDIUM:
+ cdma->med_prio_count++;
+ break;
+ case NVHOST_PRIORITY_LOW:
+ cdma->low_prio_count++;
+ break;
+ }
}
/**
@@ -200,6 +212,19 @@ static void update_cdma_locked(struct nvhost_cdma *cdma)
}
list_del(&job->list);
+
+ switch (job->priority) {
+ case NVHOST_PRIORITY_HIGH:
+ cdma->high_prio_count--;
+ break;
+ case NVHOST_PRIORITY_MEDIUM:
+ cdma->med_prio_count--;
+ break;
+ case NVHOST_PRIORITY_LOW:
+ cdma->low_prio_count--;
+ break;
+ }
+
nvhost_job_put(job);
}
@@ -466,6 +491,12 @@ void nvhost_cdma_end(struct nvhost_cdma *cdma,
if (job->timeout && was_idle)
cdma_start_timer_locked(cdma, job);
+ trace_nvhost_cdma_end(job->ch->dev->name,
+ job->priority,
+ job->ch->cdma.high_prio_count,
+ job->ch->cdma.med_prio_count,
+ job->ch->cdma.low_prio_count);
+
mutex_unlock(&cdma->lock);
}
@@ -490,6 +521,8 @@ int nvhost_cdma_flush(struct nvhost_cdma *cdma, int timeout)
unsigned int space, err = 0;
unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout);
+ trace_nvhost_cdma_flush(cdma_to_channel(cdma)->dev->name, timeout);
+
/*
* Wait for at most timeout ms. Recalculate timeout at each iteration
* to better keep within given timeout.
diff --git a/drivers/video/tegra/host/nvhost_cdma.h b/drivers/video/tegra/host/nvhost_cdma.h
index 98393f0cc765..2056774a7bc7 100644
--- a/drivers/video/tegra/host/nvhost_cdma.h
+++ b/drivers/video/tegra/host/nvhost_cdma.h
@@ -99,6 +99,9 @@ struct nvhost_cdma {
struct buffer_timeout timeout; /* channel's timeout state/wq */
bool running;
bool torndown;
+ int high_prio_count;
+ int med_prio_count;
+ int low_prio_count;
};
#define cdma_to_channel(cdma) container_of(cdma, struct nvhost_channel, cdma)
diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c
index ef8886fe4652..ad303cf0a22d 100644
--- a/drivers/video/tegra/host/nvhost_channel.c
+++ b/drivers/video/tegra/host/nvhost_channel.c
@@ -51,10 +51,26 @@ int nvhost_channel_init(struct nvhost_channel *ch,
int nvhost_channel_submit(struct nvhost_job *job)
{
- /* Low priority submits wait until sync queue is empty. Ignores result
- * from nvhost_cdma_flush, as we submit either when push buffer is
- * empty or when we reach the timeout. */
- if (job->priority < NVHOST_PRIORITY_MEDIUM)
+ /*
+ * Check if queue has higher priority jobs running. If so, wait until
+ * queue is empty. Ignores result from nvhost_cdma_flush, as we submit
+ * either when push buffer is empty or when we reach the timeout.
+ */
+ int higher_count = 0;
+
+ switch (job->priority) {
+ case NVHOST_PRIORITY_HIGH:
+ higher_count = 0;
+ break;
+ case NVHOST_PRIORITY_MEDIUM:
+ higher_count = job->ch->cdma.high_prio_count;
+ break;
+ case NVHOST_PRIORITY_LOW:
+ higher_count = job->ch->cdma.high_prio_count
+ + job->ch->cdma.med_prio_count;
+ break;
+ }
+ if (higher_count > 0)
(void)nvhost_cdma_flush(&job->ch->cdma,
NVHOST_CHANNEL_LOW_PRIO_MAX_WAIT);
diff --git a/drivers/video/tegra/host/nvhost_intr.c b/drivers/video/tegra/host/nvhost_intr.c
index ba821f694cb4..af2e3ad1bdb5 100644
--- a/drivers/video/tegra/host/nvhost_intr.c
+++ b/drivers/video/tegra/host/nvhost_intr.c
@@ -128,12 +128,16 @@ static void action_submit_complete(struct nvhost_waitlist *waiter)
struct nvhost_channel *channel = waiter->data;
int nr_completed = waiter->count;
+ nvhost_cdma_update(&channel->cdma);
+ nvhost_module_idle_mult(channel->dev, nr_completed);
+
/* Add nr_completed to trace */
trace_nvhost_channel_submit_complete(channel->dev->name,
- nr_completed, waiter->thresh);
+ nr_completed, waiter->thresh,
+ channel->cdma.high_prio_count,
+ channel->cdma.med_prio_count,
+ channel->cdma.low_prio_count);
- nvhost_cdma_update(&channel->cdma);
- nvhost_module_idle_mult(channel->dev, nr_completed);
}
static void action_ctxsave(struct nvhost_waitlist *waiter)