diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 5f9711d32..99cfb07ea 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -630,6 +630,17 @@ static int gk20a_channel_cycle_stats_snapshot(struct channel_gk20a *ch, } #endif +static int gk20a_channel_set_wdt_status(struct channel_gk20a *ch, + struct nvgpu_channel_wdt_args *args) +{ + if (args->wdt_status == NVGPU_IOCTL_CHANNEL_DISABLE_WDT) + ch->wdt_enabled = false; + else if (args->wdt_status == NVGPU_IOCTL_CHANNEL_ENABLE_WDT) + ch->wdt_enabled = true; + + return 0; +} + static int gk20a_init_error_notifier(struct channel_gk20a *ch, struct nvgpu_set_error_notifier *args) { void *va; @@ -1424,12 +1435,7 @@ bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch, static u32 gk20a_get_channel_watchdog_timeout(struct channel_gk20a *ch) { struct gk20a_platform *platform = gk20a_get_platform(ch->g->dev); - - if (ch->g->timeouts_enabled && ch->g->ch_wdt_enabled && - platform->ch_wdt_timeout_ms) - return platform->ch_wdt_timeout_ms; - else - return (u32)MAX_SCHEDULE_TIMEOUT; + return platform->ch_wdt_timeout_ms; } static u32 get_gp_free_count(struct channel_gk20a *c) @@ -1519,6 +1525,14 @@ static void trace_write_pushbuffer_range(struct channel_gk20a *c, static void gk20a_channel_timeout_start(struct channel_gk20a *ch, struct channel_gk20a_job *job) { + struct gk20a_platform *platform = gk20a_get_platform(ch->g->dev); + + if (!ch->g->timeouts_enabled || !platform->ch_wdt_timeout_ms) + return; + + if (!ch->wdt_enabled) + return; + mutex_lock(&ch->timeout.lock); if (ch->timeout.initialized) { @@ -2117,6 +2131,7 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid) c->g = NULL; c->hw_chid = chid; c->bound = false; + c->wdt_enabled = true; spin_lock_init(&c->ref_obtain_lock); atomic_set(&c->ref_count, 0); c->referenceable = false; @@ -2839,6 +2854,10 @@ long gk20a_channel_ioctl(struct file *filp, gk20a_idle(dev); break; #endif + case NVGPU_IOCTL_CHANNEL_WDT: + err = gk20a_channel_set_wdt_status(ch, + (struct nvgpu_channel_wdt_args *)buf); + break; default: dev_dbg(&dev->dev, "unrecognized ioctl cmd: 0x%x", cmd); err = -ENOTTY; diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index 245db56a0..55528dd9f 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h @@ -92,6 +92,7 @@ struct channel_gk20a { wait_queue_head_t ref_count_dec_wq; int hw_chid; + bool wdt_enabled; bool bound; bool first_init; bool vpr; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 79218c971..9bbc9bd83 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -1436,7 +1436,6 @@ static int gk20a_probe(struct platform_device *dev) CONFIG_GK20A_DEFAULT_TIMEOUT; if (tegra_platform_is_silicon()) gk20a->timeouts_enabled = true; - gk20a->ch_wdt_enabled = true; gk20a->timeslice_low_priority_us = 1300; gk20a->timeslice_medium_priority_us = 2600; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index fe51f356c..51955a3ac 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -499,7 +499,6 @@ struct gk20a { u32 gr_idle_timeout_default; u32 timeouts_enabled; - u32 ch_wdt_enabled; struct mutex ch_wdt_lock; /* Channel priorities */ diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h index 025f2c9bd..976464e46 100644 --- a/include/uapi/linux/nvgpu.h +++ b/include/uapi/linux/nvgpu.h @@ -802,6 +802,13 @@ struct nvgpu_cycle_stats_snapshot_args { #define NVGPU_IOCTL_CHANNEL_CYCLE_STATS_SNAPSHOT_CMD_ATTACH 1 #define NVGPU_IOCTL_CHANNEL_CYCLE_STATS_SNAPSHOT_CMD_DETACH 2 +/* disable watchdog per-channel */ +struct nvgpu_channel_wdt_args { + __u32 wdt_status; + __u32 padding; +}; +#define NVGPU_IOCTL_CHANNEL_DISABLE_WDT 1 +#define NVGPU_IOCTL_CHANNEL_ENABLE_WDT 2 #define NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD \ _IOW(NVGPU_IOCTL_MAGIC, 5, struct nvgpu_set_nvmap_fd_args) @@ -843,9 +850,11 @@ struct nvgpu_cycle_stats_snapshot_args { _IOW(NVGPU_IOCTL_MAGIC, 117, struct nvgpu_channel_events_ctrl_args) #define NVGPU_IOCTL_CHANNEL_CYCLE_STATS_SNAPSHOT \ _IOWR(NVGPU_IOCTL_MAGIC, 118, struct nvgpu_cycle_stats_snapshot_args) +#define NVGPU_IOCTL_CHANNEL_WDT \ + _IOW(NVGPU_IOCTL_MAGIC, 119, struct nvgpu_channel_wdt_args) #define NVGPU_IOCTL_CHANNEL_LAST \ - _IOC_NR(NVGPU_IOCTL_CHANNEL_CYCLE_STATS_SNAPSHOT) + _IOC_NR(NVGPU_IOCTL_CHANNEL_WDT) #define NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvgpu_submit_gpfifo_args) /*