]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: host: Move priority check to device code
authorShridhar Rasal <srasal@nvidia.com>
Thu, 12 Feb 2015 10:35:12 +0000 (16:05 +0530)
committerArto Merilainen <amerilainen@nvidia.com>
Wed, 11 Mar 2015 08:20:39 +0000 (01:20 -0700)
- This moves priority support code to device file.
- Adds priority lock to update channel priority.
- Adds callback to lower channel priority.

Bug 1526002

Change-Id: Ie2040a145060400dadab4bd1c84611007616d8d4
Signed-off-by: Shridhar Rasal <srasal@nvidia.com>
Reviewed-on: http://git-master/r/707310
Reviewed-by: Arto Merilainen <amerilainen@nvidia.com>
Tested-by: Arto Merilainen <amerilainen@nvidia.com>
drivers/video/tegra/host/host1x/host1x.c
drivers/video/tegra/host/host1x/host1x.h
drivers/video/tegra/host/host1x/host1x_channel.c
drivers/video/tegra/host/nvhost_channel.c
drivers/video/tegra/host/nvhost_channel.h

index 0b8250c60095d3e2c39af5e87cac47cc53f0bc46..870ad93942dbb0f0c546a98378f5a9c2aa482aa1 100644 (file)
@@ -833,6 +833,7 @@ static int nvhost_probe(struct platform_device *dev)
        INIT_LIST_HEAD(&host->vm_list);
        mutex_init(&host->vm_mutex);
        mutex_init(&pdata->lock);
+       mutex_init(&host->priority_lock);
 
        /* Copy host1x parameters. The private_data gets replaced
         * by nvhost_master later */
index 47f63805fc389a055fd99fbee86a737e21c112af..069cc22a909200bf077f39d3ff0a6fc25f3559ef 100644 (file)
@@ -87,6 +87,7 @@ struct nvhost_master {
        struct nvhost_channel **chlist; /* channel list */
        struct mutex chlist_mutex;      /* mutex for channel list */
        unsigned long allocated_channels;
+       struct mutex priority_lock;     /* mutex for priority update */
 
        /* nvhost vm specific structures */
        struct list_head static_mappings_list;
index 5bcb8092d9b7519b61fc545a2de19b5fa5650286..39978a0acc1a5d0f74fec230e3eae0d72a7a4a69 100644 (file)
@@ -31,6 +31,8 @@
 #include "class_ids.h"
 #include "debug.h"
 
+#define NVHOST_CHANNEL_LOW_PRIO_MAX_WAIT 50
+
 static void submit_work_done_increment(struct nvhost_job *job)
 {
        struct nvhost_channel *ch = job->ch;
@@ -242,6 +244,34 @@ static void submit_gathers(struct nvhost_job *job)
        }
 }
 
+static int host1x_channel_prio_check(struct nvhost_job *job)
+{
+       /*
+        * 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);
+
+       return 0;
+}
+
 static int host1x_channel_submit(struct nvhost_job *job)
 {
        struct nvhost_channel *ch = job->ch;
@@ -252,6 +282,8 @@ static int host1x_channel_submit(struct nvhost_job *job)
        void *completed_waiters[job->num_syncpts];
        struct nvhost_job_syncpt *hwctx_sp = job->sp + job->hwctx_syncpt_idx;
 
+       host1x_channel_prio_check(job);
+
        memset(completed_waiters, 0, sizeof(void *) * job->num_syncpts);
 
        /* Turn on the client module and host1x */
index f445794f313336a5cb75af75a7f6b8ad295182b5..ff7e6740810241a89276988f9b49c05617ee21f3 100644 (file)
@@ -157,6 +157,9 @@ static int nvhost_channel_unmap_locked(struct nvhost_channel *ch)
        /* turn off channel cdma */
        channel_cdma_op().stop(&ch->cdma);
 
+       if (channel_op(ch).set_low_ch_prio)
+               channel_op(ch).set_low_ch_prio(ch);
+
        /* this is used only if we map channel on open */
        if (nvhost_get_channel_policy() == MAP_CHANNEL_ON_OPEN)
                pdata->num_mapped_chs--;
@@ -333,34 +336,10 @@ void nvhost_channel_init_gather_filter(struct nvhost_channel *ch)
 
 int nvhost_channel_submit(struct nvhost_job *job)
 {
-       /*
-        * 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);
-
        return channel_op(job->ch).submit(job);
 }
 EXPORT_SYMBOL(nvhost_channel_submit);
 
-
 void nvhost_getchannel(struct nvhost_channel *ch)
 {
        struct nvhost_device_data *pdata = platform_get_drvdata(ch->dev);
index 13b5c68ef6a1d414b0e185369b6adc02b3355e06..b29c99a1d394345756a3073f6eb0288336958452 100644 (file)
@@ -40,6 +40,7 @@ struct nvhost_channel_ops {
                    struct nvhost_master *);
        int (*submit)(struct nvhost_job *job);
        int (*init_gather_filter)(struct nvhost_channel *ch);
+       int (*set_low_ch_prio)(struct nvhost_channel *ch);
 };
 
 struct nvhost_channel {