From 9592a4e6fce8204e9ada54ba00902e792199fec5 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Wed, 28 Oct 2015 16:13:14 +0530 Subject: gpu: nvgpu: IOCTL to set TSG timeslice Add new IOCTL NVGPU_IOCTL_TSG_SET_PRIORITY to allow setting timeslice for entire TSG Return error from channel specific IOCTL_CHANNEL_SET_PRIORITY if the channel is part of TSG Separate out API gk20a_channel_get_timescale_from_timeslice() to get timeslice_timeout and scale from timeslice period Use this API to get timeslice_timeout and scale for TSG and store it in tsg_gk20a structure Then trigger runlist update so that new timeslice values will be re-written to runlist for TSG Bug 200146615 Change-Id: I555467d034f81b372b31372f0835d72b1c159508 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/824206 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 56 +++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 5b5da633..688992c6 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -132,24 +132,14 @@ static int channel_gk20a_commit_userd(struct channel_gk20a *c) return 0; } -static int channel_gk20a_set_schedule_params(struct channel_gk20a *c, - u32 timeslice_timeout) +int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g, + int timeslice_period, + int *__timeslice_timeout, int *__timeslice_scale) { - void *inst_ptr; - struct gk20a_platform *platform = platform_get_drvdata(c->g->dev); - int shift = 3; - int value = scale_ptimer(timeslice_timeout, + struct gk20a_platform *platform = platform_get_drvdata(g->dev); + int value = scale_ptimer(timeslice_period, platform->ptimerscaling10x); - - inst_ptr = c->inst_block.cpu_va; - if (!inst_ptr) - return -ENOMEM; - - /* disable channel */ - c->g->ops.fifo.disable_channel(c); - - /* preempt the channel */ - WARN_ON(c->g->ops.fifo.preempt_channel(c->g, c->hw_chid)); + int shift = 3; /* value field is 8 bits long */ while (value >= 1 << 8) { @@ -164,6 +154,31 @@ static int channel_gk20a_set_schedule_params(struct channel_gk20a *c, shift = 10; } + *__timeslice_timeout = value; + *__timeslice_scale = shift; + + return 0; +} + +static int channel_gk20a_set_schedule_params(struct channel_gk20a *c, + u32 timeslice_period) +{ + void *inst_ptr; + int shift = 0, value = 0; + + inst_ptr = c->inst_block.cpu_va; + if (!inst_ptr) + return -ENOMEM; + + gk20a_channel_get_timescale_from_timeslice(c->g, timeslice_period, + &value, &shift); + + /* disable channel */ + c->g->ops.fifo.disable_channel(c); + + /* preempt the channel */ + WARN_ON(c->g->ops.fifo.preempt_channel(c->g, c->hw_chid)); + /* set new timeslice */ gk20a_mem_wr32(inst_ptr, ram_fc_runlist_timeslice_w(), value | (shift << 12) | @@ -2350,6 +2365,13 @@ static int gk20a_channel_set_priority(struct channel_gk20a *ch, u32 priority) { u32 timeslice_timeout; + + if (gk20a_is_channel_marked_as_tsg(ch)) { + gk20a_err(dev_from_gk20a(ch->g), + "invalid operation for TSG!\n"); + return -EINVAL; + } + /* set priority of graphics channel */ switch (priority) { case NVGPU_PRIORITY_LOW: @@ -2714,7 +2736,7 @@ long gk20a_channel_ioctl(struct file *filp, __func__, cmd); break; } - gk20a_channel_set_priority(ch, + err = gk20a_channel_set_priority(ch, ((struct nvgpu_set_priority_args *)buf)->priority); gk20a_idle(dev); break; -- cgit v1.2.2