diff options
-rw-r--r-- | arch/arm/mach-tegra/include/mach/nvhost.h | 12 | ||||
-rw-r--r-- | drivers/video/tegra/dc/overlay.c | 3 | ||||
-rw-r--r-- | drivers/video/tegra/fb.c | 3 | ||||
-rw-r--r-- | drivers/video/tegra/host/dev.c | 11 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_syncpt.c | 17 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_syncpt.h | 11 |
6 files changed, 45 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/include/mach/nvhost.h b/arch/arm/mach-tegra/include/mach/nvhost.h index fc18f2e6292e..b769147ab1f4 100644 --- a/arch/arm/mach-tegra/include/mach/nvhost.h +++ b/arch/arm/mach-tegra/include/mach/nvhost.h @@ -161,6 +161,13 @@ struct nvhost_ctrl_syncpt_wait_args { __s32 timeout; }; +struct nvhost_ctrl_syncpt_waitex_args { + __u32 id; + __u32 thresh; + __s32 timeout; + __u32 value; +}; + struct nvhost_ctrl_module_mutex_args { __u32 id; __u32 lock; @@ -187,8 +194,11 @@ struct nvhost_ctrl_module_regrdwr_args { #define NVHOST_IOCTL_CTRL_MODULE_REGRDWR \ _IOWR(NVHOST_IOCTL_MAGIC, 5, struct nvhost_ctrl_module_regrdwr_args) +#define NVHOST_IOCTL_CTRL_SYNCPT_WAITEX \ + _IOWR(NVHOST_IOCTL_MAGIC, 6, struct nvhost_ctrl_syncpt_waitex_args) + #define NVHOST_IOCTL_CTRL_LAST \ - _IOC_NR(NVHOST_IOCTL_CTRL_MODULE_REGRDWR) + _IOC_NR(NVHOST_IOCTL_CTRL_SYNCPT_WAITEX) #define NVHOST_IOCTL_CTRL_MAX_ARG_SIZE sizeof(struct nvhost_ctrl_module_regrdwr_args) #endif diff --git a/drivers/video/tegra/dc/overlay.c b/drivers/video/tegra/dc/overlay.c index 863666d96e51..f24476c2489a 100644 --- a/drivers/video/tegra/dc/overlay.c +++ b/drivers/video/tegra/dc/overlay.c @@ -201,7 +201,8 @@ static int tegra_overlay_set_windowattr(struct tegra_overlay_info *overlay, nvhost_syncpt_wait_timeout(&overlay->ndev->host->syncpt, flip_win->attr.pre_syncpt_id, flip_win->attr.pre_syncpt_val, - msecs_to_jiffies(500)); + msecs_to_jiffies(500), + NULL); } /* Store the blend state incase we need to reorder later */ diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c index b64c4bb6bb97..b09c30bfc3be 100644 --- a/drivers/video/tegra/fb.c +++ b/drivers/video/tegra/fb.c @@ -463,7 +463,8 @@ static int tegra_fb_set_windowattr(struct tegra_fb_info *tegra_fb, nvhost_syncpt_wait_timeout(&tegra_fb->ndev->host->syncpt, flip_win->attr.pre_syncpt_id, flip_win->attr.pre_syncpt_val, - msecs_to_jiffies(500)); + msecs_to_jiffies(500), + NULL); } diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c index fdbf5cc8efc1..7e73d26a072e 100644 --- a/drivers/video/tegra/host/dev.c +++ b/drivers/video/tegra/host/dev.c @@ -499,9 +499,9 @@ static int nvhost_ioctl_ctrl_syncpt_incr( return 0; } -static int nvhost_ioctl_ctrl_syncpt_wait( +static int nvhost_ioctl_ctrl_syncpt_waitex( struct nvhost_ctrl_userctx *ctx, - struct nvhost_ctrl_syncpt_wait_args *args) + struct nvhost_ctrl_syncpt_waitex_args *args) { u32 timeout; if (args->id >= NV_HOST1X_SYNCPT_NB_PTS) @@ -512,7 +512,7 @@ static int nvhost_ioctl_ctrl_syncpt_wait( timeout = (u32)msecs_to_jiffies(args->timeout); return nvhost_syncpt_wait_timeout(&ctx->dev->syncpt, args->id, - args->thresh, timeout); + args->thresh, timeout, &args->value); } static int nvhost_ioctl_ctrl_module_mutex( @@ -610,7 +610,7 @@ static long nvhost_ctrlctl(struct file *filp, err = nvhost_ioctl_ctrl_syncpt_incr(priv, (void *)buf); break; case NVHOST_IOCTL_CTRL_SYNCPT_WAIT: - err = nvhost_ioctl_ctrl_syncpt_wait(priv, (void *)buf); + err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf); break; case NVHOST_IOCTL_CTRL_MODULE_MUTEX: err = nvhost_ioctl_ctrl_module_mutex(priv, (void *)buf); @@ -618,6 +618,9 @@ static long nvhost_ctrlctl(struct file *filp, case NVHOST_IOCTL_CTRL_MODULE_REGRDWR: err = nvhost_ioctl_ctrl_module_regrdwr(priv, (void *)buf); break; + case NVHOST_IOCTL_CTRL_SYNCPT_WAITEX: + err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf); + break; default: err = -ENOTTY; break; diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c index 1881716ed428..dc9f911ac90c 100644 --- a/drivers/video/tegra/host/nvhost_syncpt.c +++ b/drivers/video/tegra/host/nvhost_syncpt.c @@ -161,17 +161,23 @@ void nvhost_syncpt_incr(struct nvhost_syncpt *sp, u32 id) * Main entrypoint for syncpoint value waits. */ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, - u32 thresh, u32 timeout) + u32 thresh, u32 timeout, u32 *value) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); void *ref; int err = 0; + if (value) + *value = 0; + BUG_ON(!check_max(sp, id, thresh)); /* first check cache */ - if (nvhost_syncpt_min_cmp(sp, id, thresh)) + if (nvhost_syncpt_min_cmp(sp, id, thresh)) { + if (value) + *value = nvhost_syncpt_read_min(sp, id); return 0; + } /* keep host alive */ nvhost_module_busy(&syncpt_to_dev(sp)->mod); @@ -179,8 +185,11 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, if (client_managed(id) || !nvhost_syncpt_min_eq_max(sp, id)) { /* try to read from register */ u32 val = nvhost_syncpt_update_min(sp, id); - if ((s32)(val - thresh) >= 0) + if ((s32)(val - thresh) >= 0) { + if (value) + *value = val; goto done; + } } if (!timeout) { @@ -202,6 +211,8 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, nvhost_syncpt_min_cmp(sp, id, thresh), check); if (remain > 0 || nvhost_syncpt_min_cmp(sp, id, thresh)) { + if (value) + *value = nvhost_syncpt_read_min(sp, id); err = 0; break; } diff --git a/drivers/video/tegra/host/nvhost_syncpt.h b/drivers/video/tegra/host/nvhost_syncpt.h index b4ce3c6ee6d4..992162b17e93 100644 --- a/drivers/video/tegra/host/nvhost_syncpt.h +++ b/drivers/video/tegra/host/nvhost_syncpt.h @@ -101,6 +101,12 @@ static inline u32 nvhost_syncpt_read_max(struct nvhost_syncpt *sp, u32 id) return (u32)atomic_read(&sp->max_val[id]); } +static inline u32 nvhost_syncpt_read_min(struct nvhost_syncpt *sp, u32 id) +{ + smp_rmb(); + return (u32)atomic_read(&sp->min_val[id]); +} + /** * Returns true if syncpoint has reached threshold */ @@ -138,11 +144,12 @@ u32 nvhost_syncpt_read(struct nvhost_syncpt *sp, u32 id); void nvhost_syncpt_incr(struct nvhost_syncpt *sp, u32 id); int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id, u32 thresh, - u32 timeout); + u32 timeout, u32 *value); static inline int nvhost_syncpt_wait(struct nvhost_syncpt *sp, u32 id, u32 thresh) { - return nvhost_syncpt_wait_timeout(sp, id, thresh, MAX_SCHEDULE_TIMEOUT); + return nvhost_syncpt_wait_timeout(sp, id, thresh, + MAX_SCHEDULE_TIMEOUT, NULL); } int nvhost_syncpt_wait_check(struct nvmap_client *nvmap, |