diff options
-rw-r--r-- | arch/arm/mach-tegra/include/mach/nvmap.h | 1 | ||||
-rw-r--r-- | drivers/video/tegra/host/dev.c | 43 | ||||
-rw-r--r-- | drivers/video/tegra/nvmap/nvmap.c | 1 | ||||
-rw-r--r-- | include/linux/nvhost_ioctl.h | 12 | ||||
-rw-r--r-- | include/trace/events/nvhost.h | 12 |
5 files changed, 52 insertions, 17 deletions
diff --git a/arch/arm/mach-tegra/include/mach/nvmap.h b/arch/arm/mach-tegra/include/mach/nvmap.h index ad23caa45cfb..cb5375226bc8 100644 --- a/arch/arm/mach-tegra/include/mach/nvmap.h +++ b/arch/arm/mach-tegra/include/mach/nvmap.h @@ -65,6 +65,7 @@ struct nvmap_pinarray_elem { __u32 patch_offset; __u32 pin_mem; __u32 pin_offset; + __u32 reloc_shift; }; /* handle_ref objects are client-local references to an nvmap_handle; diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c index 1767e53ca884..fa5cbaeefa2b 100644 --- a/drivers/video/tegra/host/dev.c +++ b/drivers/video/tegra/host/dev.c @@ -57,6 +57,7 @@ struct nvhost_channel_userctx { struct nvhost_channel *ch; struct nvhost_hwctx *hwctx; struct nvhost_submit_hdr_ext hdr; + int num_relocshifts; struct nvmap_handle_ref *gather_mem; u32 *gathers; u32 *cur_gather; @@ -219,6 +220,9 @@ static int set_submit(struct nvhost_channel_userctx *ctx) ctx->cur_waitchk = ctx->waitchks; ctx->pinarray_size = 0; + if (ctx->hdr.submit_version >= NVHOST_SUBMIT_VERSION_V2) + ctx->num_relocshifts = ctx->hdr.num_relocs; + return 0; } @@ -226,6 +230,7 @@ static void reset_submit(struct nvhost_channel_userctx *ctx) { ctx->hdr.num_cmdbufs = 0; ctx->hdr.num_relocs = 0; + ctx->num_relocshifts = 0; ctx->hdr.num_waitchks = 0; } @@ -239,6 +244,7 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, while (remaining) { size_t consumed; if (!priv->hdr.num_relocs && + !priv->num_relocshifts && !priv->hdr.num_cmdbufs && !priv->hdr.num_waitchks) { consumed = sizeof(struct nvhost_submit_hdr); @@ -270,20 +276,17 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, cmdbuf.mem, cmdbuf.words, cmdbuf.offset); priv->hdr.num_cmdbufs--; } else if (priv->hdr.num_relocs) { - int numrelocs = remaining / sizeof(struct nvhost_reloc); - if (!numrelocs) + consumed = sizeof(struct nvhost_reloc); + if (remaining < consumed) break; - numrelocs = min_t(int, numrelocs, priv->hdr.num_relocs); - consumed = numrelocs * sizeof(struct nvhost_reloc); if (copy_from_user(&priv->pinarray[priv->pinarray_size], buf, consumed)) { err = -EFAULT; break; } - trace_nvhost_channel_write_relocs(priv->ch->desc->name, - numrelocs); - priv->pinarray_size += numrelocs; - priv->hdr.num_relocs -= numrelocs; + trace_nvhost_channel_write_reloc(priv->ch->desc->name); + priv->pinarray_size++; + priv->hdr.num_relocs--; } else if (priv->hdr.num_waitchks) { int numwaitchks = (remaining / sizeof(struct nvhost_waitchk)); @@ -301,6 +304,18 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, priv->hdr.waitchk_mask); priv->cur_waitchk += numwaitchks; priv->hdr.num_waitchks -= numwaitchks; + } else if (priv->num_relocshifts) { + int next_shift = + priv->pinarray_size - priv->num_relocshifts; + consumed = sizeof(struct nvhost_reloc_shift); + if (remaining < consumed) + break; + if (copy_from_user(&priv->pinarray[next_shift].reloc_shift, + buf, consumed)) { + err = -EFAULT; + break; + } + priv->num_relocshifts--; } else { err = -EFAULT; break; @@ -420,6 +435,7 @@ static long nvhost_channelctl(struct file *filp, struct nvhost_submit_hdr_ext *hdr; if (priv->hdr.num_relocs || + priv->num_relocshifts || priv->hdr.num_cmdbufs || priv->hdr.num_waitchks) { reset_submit(priv); @@ -687,6 +703,14 @@ static int nvhost_ioctl_ctrl_module_regrdwr( return 0; } +static int nvhost_ioctl_ctrl_get_version( + struct nvhost_ctrl_userctx *ctx, + struct nvhost_get_param_args *args) +{ + args->value = NVHOST_SUBMIT_VERSION_MAX_SUPPORTED; + return 0; +} + static long nvhost_ctrlctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -725,6 +749,9 @@ static long nvhost_ctrlctl(struct file *filp, case NVHOST_IOCTL_CTRL_SYNCPT_WAITEX: err = nvhost_ioctl_ctrl_syncpt_waitex(priv, (void *)buf); break; + case NVHOST_IOCTL_CTRL_GET_VERSION: + err = nvhost_ioctl_ctrl_get_version(priv, (void *)buf); + break; default: err = -ENOTTY; break; diff --git a/drivers/video/tegra/nvmap/nvmap.c b/drivers/video/tegra/nvmap/nvmap.c index 0bf4d884aa81..5fcdee61b71c 100644 --- a/drivers/video/tegra/nvmap/nvmap.c +++ b/drivers/video/tegra/nvmap/nvmap.c @@ -423,6 +423,7 @@ static int nvmap_reloc_pin_array(struct nvmap_client *client, } reloc_addr = handle_phys(pin) + arr[i].pin_offset; + reloc_addr >>= arr[i].reloc_shift; __raw_writel(reloc_addr, addr + (phys & ~PAGE_MASK)); } diff --git a/include/linux/nvhost_ioctl.h b/include/linux/nvhost_ioctl.h index 31ff22f45fb9..a1fc0b7cd247 100644 --- a/include/linux/nvhost_ioctl.h +++ b/include/linux/nvhost_ioctl.h @@ -48,7 +48,8 @@ struct nvhost_submit_hdr { #define NVHOST_SUBMIT_VERSION_V0 0x0 #define NVHOST_SUBMIT_VERSION_V1 0x1 -#define NVHOST_SUBMIT_VERSION_MAX_SUPPORTED NVHOST_SUBMIT_VERSION_V1 +#define NVHOST_SUBMIT_VERSION_V2 0x2 +#define NVHOST_SUBMIT_VERSION_MAX_SUPPORTED NVHOST_SUBMIT_VERSION_V2 /* version 1 header (used with ioctl() submit interface) */ struct nvhost_submit_hdr_ext { @@ -75,6 +76,10 @@ struct nvhost_reloc { __u32 target_offset; }; +struct nvhost_reloc_shift { + __u32 shift; +}; + struct nvhost_waitchk { __u32 mem; __u32 offset; @@ -188,8 +193,11 @@ 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_GET_VERSION \ + _IOR(NVHOST_IOCTL_MAGIC, 7, struct nvhost_get_param_args) + #define NVHOST_IOCTL_CTRL_LAST \ - _IOC_NR(NVHOST_IOCTL_CTRL_SYNCPT_WAITEX) + _IOC_NR(NVHOST_IOCTL_CTRL_GET_VERSION) #define NVHOST_IOCTL_CTRL_MAX_ARG_SIZE \ sizeof(struct nvhost_ctrl_module_regrdwr_args) diff --git a/include/trace/events/nvhost.h b/include/trace/events/nvhost.h index a0184440a09c..6c266b9f2ea4 100644 --- a/include/trace/events/nvhost.h +++ b/include/trace/events/nvhost.h @@ -172,23 +172,21 @@ TRACE_EVENT(nvhost_channel_write_cmdbuf_data, __entry->cmdbuf ? __entry->words * 4 : 0)) ); -TRACE_EVENT(nvhost_channel_write_relocs, - TP_PROTO(const char *name, u32 relocs), +TRACE_EVENT(nvhost_channel_write_reloc, + TP_PROTO(const char *name), - TP_ARGS(name, relocs), + TP_ARGS(name), TP_STRUCT__entry( __field(const char *, name) - __field(u32, relocs) ), TP_fast_assign( __entry->name = name; - __entry->relocs = relocs; ), - TP_printk("name=%s, relocs=%u", - __entry->name, __entry->relocs) + TP_printk("name=%s", + __entry->name) ); TRACE_EVENT(nvhost_channel_write_waitchks, |