- 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>
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 */
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;
#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;
}
}
+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;
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 */
/* 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--;
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);
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 {