mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
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 <dnibade@nvidia.com> Reviewed-on: http://git-master/r/824206 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
Terje Bergstrom
parent
8d279dbac1
commit
9592a4e6fc
@@ -132,24 +132,14 @@ static int channel_gk20a_commit_userd(struct channel_gk20a *c)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int channel_gk20a_set_schedule_params(struct channel_gk20a *c,
|
int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g,
|
||||||
u32 timeslice_timeout)
|
int timeslice_period,
|
||||||
|
int *__timeslice_timeout, int *__timeslice_scale)
|
||||||
{
|
{
|
||||||
void *inst_ptr;
|
struct gk20a_platform *platform = platform_get_drvdata(g->dev);
|
||||||
struct gk20a_platform *platform = platform_get_drvdata(c->g->dev);
|
int value = scale_ptimer(timeslice_period,
|
||||||
int shift = 3;
|
|
||||||
int value = scale_ptimer(timeslice_timeout,
|
|
||||||
platform->ptimerscaling10x);
|
platform->ptimerscaling10x);
|
||||||
|
int shift = 3;
|
||||||
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));
|
|
||||||
|
|
||||||
/* value field is 8 bits long */
|
/* value field is 8 bits long */
|
||||||
while (value >= 1 << 8) {
|
while (value >= 1 << 8) {
|
||||||
@@ -164,6 +154,31 @@ static int channel_gk20a_set_schedule_params(struct channel_gk20a *c,
|
|||||||
shift = 10;
|
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 */
|
/* set new timeslice */
|
||||||
gk20a_mem_wr32(inst_ptr, ram_fc_runlist_timeslice_w(),
|
gk20a_mem_wr32(inst_ptr, ram_fc_runlist_timeslice_w(),
|
||||||
value | (shift << 12) |
|
value | (shift << 12) |
|
||||||
@@ -2350,6 +2365,13 @@ static int gk20a_channel_set_priority(struct channel_gk20a *ch,
|
|||||||
u32 priority)
|
u32 priority)
|
||||||
{
|
{
|
||||||
u32 timeslice_timeout;
|
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 */
|
/* set priority of graphics channel */
|
||||||
switch (priority) {
|
switch (priority) {
|
||||||
case NVGPU_PRIORITY_LOW:
|
case NVGPU_PRIORITY_LOW:
|
||||||
@@ -2714,7 +2736,7 @@ long gk20a_channel_ioctl(struct file *filp,
|
|||||||
__func__, cmd);
|
__func__, cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gk20a_channel_set_priority(ch,
|
err = gk20a_channel_set_priority(ch,
|
||||||
((struct nvgpu_set_priority_args *)buf)->priority);
|
((struct nvgpu_set_priority_args *)buf)->priority);
|
||||||
gk20a_idle(dev);
|
gk20a_idle(dev);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -253,4 +253,9 @@ int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
|
|||||||
u64 gpfifo_base, u32 gpfifo_entries, u32 flags);
|
u64 gpfifo_base, u32 gpfifo_entries, u32 flags);
|
||||||
void channel_gk20a_enable(struct channel_gk20a *ch);
|
void channel_gk20a_enable(struct channel_gk20a *ch);
|
||||||
void gk20a_channel_timeout_restart_all_channels(struct gk20a *g);
|
void gk20a_channel_timeout_restart_all_channels(struct gk20a *g);
|
||||||
|
|
||||||
|
int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g,
|
||||||
|
int timeslice_period,
|
||||||
|
int *__timeslice_timeout, int *__timeslice_scale);
|
||||||
|
|
||||||
#endif /* CHANNEL_GK20A_H */
|
#endif /* CHANNEL_GK20A_H */
|
||||||
|
|||||||
@@ -2115,6 +2115,32 @@ static int gk20a_fifo_runlist_wait_pending(struct gk20a *g, u32 runlist_id)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32 gk20a_get_tsg_runlist_entry_0(struct tsg_gk20a *tsg)
|
||||||
|
{
|
||||||
|
u32 runlist_entry_0 = 0;
|
||||||
|
|
||||||
|
if (tsg->timeslice_timeout)
|
||||||
|
runlist_entry_0 = ram_rl_entry_id_f(tsg->tsgid) |
|
||||||
|
ram_rl_entry_type_f(ram_rl_entry_type_tsg_f()) |
|
||||||
|
ram_rl_entry_timeslice_scale_f(
|
||||||
|
tsg->timeslice_scale) |
|
||||||
|
ram_rl_entry_timeslice_timeout_f(
|
||||||
|
tsg->timeslice_timeout) |
|
||||||
|
ram_rl_entry_tsg_length_f(
|
||||||
|
tsg->num_active_channels);
|
||||||
|
else
|
||||||
|
runlist_entry_0 = ram_rl_entry_id_f(tsg->tsgid) |
|
||||||
|
ram_rl_entry_type_f(ram_rl_entry_type_tsg_f()) |
|
||||||
|
ram_rl_entry_timeslice_scale_f(
|
||||||
|
ram_rl_entry_timeslice_scale_3_f()) |
|
||||||
|
ram_rl_entry_timeslice_timeout_f(
|
||||||
|
ram_rl_entry_timeslice_timeout_128_f()) |
|
||||||
|
ram_rl_entry_tsg_length_f(
|
||||||
|
tsg->num_active_channels);
|
||||||
|
|
||||||
|
return runlist_entry_0;
|
||||||
|
}
|
||||||
|
|
||||||
static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
|
static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
|
||||||
u32 hw_chid, bool add,
|
u32 hw_chid, bool add,
|
||||||
bool wait_for_finish)
|
bool wait_for_finish)
|
||||||
@@ -2201,14 +2227,7 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id,
|
|||||||
tsg = &f->tsg[tsgid];
|
tsg = &f->tsg[tsgid];
|
||||||
/* add TSG entry */
|
/* add TSG entry */
|
||||||
gk20a_dbg_info("add TSG %d to runlist", tsg->tsgid);
|
gk20a_dbg_info("add TSG %d to runlist", tsg->tsgid);
|
||||||
runlist_entry[0] = ram_rl_entry_id_f(tsg->tsgid) |
|
runlist_entry[0] = gk20a_get_tsg_runlist_entry_0(tsg);
|
||||||
ram_rl_entry_type_f(ram_rl_entry_type_tsg_f()) |
|
|
||||||
ram_rl_entry_timeslice_scale_f(
|
|
||||||
ram_rl_entry_timeslice_scale_3_f()) |
|
|
||||||
ram_rl_entry_timeslice_timeout_f(
|
|
||||||
ram_rl_entry_timeslice_timeout_128_f()) |
|
|
||||||
ram_rl_entry_tsg_length_f(
|
|
||||||
tsg->num_active_channels);
|
|
||||||
runlist_entry[1] = 0;
|
runlist_entry[1] = 0;
|
||||||
runlist_entry += 2;
|
runlist_entry += 2;
|
||||||
count++;
|
count++;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -126,6 +126,34 @@ int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg,
|
||||||
|
u32 priority)
|
||||||
|
{
|
||||||
|
int timeslice_period;
|
||||||
|
|
||||||
|
switch (priority) {
|
||||||
|
case NVGPU_PRIORITY_LOW:
|
||||||
|
timeslice_period = g->timeslice_low_priority_us;
|
||||||
|
break;
|
||||||
|
case NVGPU_PRIORITY_MEDIUM:
|
||||||
|
timeslice_period = g->timeslice_medium_priority_us;
|
||||||
|
break;
|
||||||
|
case NVGPU_PRIORITY_HIGH:
|
||||||
|
timeslice_period = g->timeslice_high_priority_us;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("Unsupported priority");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gk20a_channel_get_timescale_from_timeslice(g, timeslice_period,
|
||||||
|
&tsg->timeslice_timeout, &tsg->timeslice_scale);
|
||||||
|
|
||||||
|
g->ops.fifo.update_runlist(g, 0, ~0, true, true);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg)
|
static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg)
|
||||||
{
|
{
|
||||||
mutex_lock(&f->tsg_inuse_mutex);
|
mutex_lock(&f->tsg_inuse_mutex);
|
||||||
@@ -320,6 +348,13 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case NVGPU_IOCTL_TSG_SET_PRIORITY:
|
||||||
|
{
|
||||||
|
err = gk20a_tsg_set_priority(g, tsg,
|
||||||
|
((struct nvgpu_set_priority_args *)buf)->priority);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gk20a_err(dev_from_gk20a(g),
|
gk20a_err(dev_from_gk20a(g),
|
||||||
"unrecognized tsg gpu ioctl cmd: 0x%x",
|
"unrecognized tsg gpu ioctl cmd: 0x%x",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
|
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms and conditions of the GNU General Public License,
|
* under the terms and conditions of the GNU General Public License,
|
||||||
@@ -42,6 +42,9 @@ struct tsg_gk20a {
|
|||||||
int num_active_channels;
|
int num_active_channels;
|
||||||
struct mutex ch_list_lock;
|
struct mutex ch_list_lock;
|
||||||
|
|
||||||
|
int timeslice_timeout;
|
||||||
|
int timeslice_scale;
|
||||||
|
|
||||||
struct gr_ctx_desc *tsg_gr_ctx;
|
struct gr_ctx_desc *tsg_gr_ctx;
|
||||||
|
|
||||||
struct vm_gk20a *vm;
|
struct vm_gk20a *vm;
|
||||||
|
|||||||
@@ -377,11 +377,13 @@ struct nvgpu_gpu_vsms_mapping {
|
|||||||
_IO(NVGPU_TSG_IOCTL_MAGIC, 4)
|
_IO(NVGPU_TSG_IOCTL_MAGIC, 4)
|
||||||
#define NVGPU_IOCTL_TSG_PREEMPT \
|
#define NVGPU_IOCTL_TSG_PREEMPT \
|
||||||
_IO(NVGPU_TSG_IOCTL_MAGIC, 5)
|
_IO(NVGPU_TSG_IOCTL_MAGIC, 5)
|
||||||
|
#define NVGPU_IOCTL_TSG_SET_PRIORITY \
|
||||||
|
_IOW(NVGPU_TSG_IOCTL_MAGIC, 6, struct nvgpu_set_priority_args)
|
||||||
|
|
||||||
#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \
|
#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \
|
||||||
sizeof(int)
|
sizeof(struct nvgpu_set_priority_args)
|
||||||
#define NVGPU_TSG_IOCTL_LAST \
|
#define NVGPU_TSG_IOCTL_LAST \
|
||||||
_IOC_NR(NVGPU_IOCTL_TSG_PREEMPT)
|
_IOC_NR(NVGPU_IOCTL_TSG_SET_PRIORITY)
|
||||||
/*
|
/*
|
||||||
* /dev/nvhost-dbg-gpu device
|
* /dev/nvhost-dbg-gpu device
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user