From 73f65f7f6898bd88fe457f96d4dc702f746058bc Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Thu, 24 May 2012 15:06:58 +0300 Subject: video: tegra: host: Replace nvmap structs with own Replace usage of nvmap_pinarray_elem with own nvhost_reloc and nvhost_reloc_shift structs. Bug 965206 Change-Id: I90618d8a34d79156d8880d9925dadbf416353811 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/104450 Reviewed-by: Juha Tukkinen Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Mayuresh Kulkarni --- drivers/video/tegra/host/bus_client.c | 39 +++++++++++++++---------- drivers/video/tegra/host/nvhost_job.c | 54 +++++++++++++++++++---------------- drivers/video/tegra/host/nvhost_job.h | 3 +- 3 files changed, 56 insertions(+), 40 deletions(-) (limited to 'drivers/video/tegra') diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index 397cd21f555d..9b71542a48aa 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -238,21 +238,28 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, cmdbuf.mem, cmdbuf.words, cmdbuf.offset); hdr->num_cmdbufs--; } else if (hdr->num_relocs) { - consumed = sizeof(struct nvhost_reloc); - if (remaining < consumed) + int numrelocs = remaining / sizeof(struct nvhost_reloc); + if (!numrelocs) break; - if (copy_from_user(&job->pinarray[job->num_relocs], + numrelocs = min_t(int, numrelocs, priv->hdr.num_relocs); + consumed = numrelocs * sizeof(struct nvhost_reloc); + if (copy_from_user(&job->relocarray[job->num_relocs], buf, consumed)) { err = -EFAULT; break; } - trace_nvhost_channel_write_reloc(chname, - job->pinarray[job->num_relocs].patch_mem, - job->pinarray[job->num_relocs].patch_offset, - job->pinarray[job->num_relocs].pin_mem, - job->pinarray[job->num_relocs].pin_offset); - job->num_relocs++; - hdr->num_relocs--; + while (numrelocs) { + struct nvhost_reloc *reloc = + &job->relocarray[job->num_relocs]; + trace_nvhost_channel_write_reloc(chname, + reloc->cmdbuf_mem, + reloc->cmdbuf_offset, + reloc->target, + reloc->target_offset); + job->num_relocs++; + hdr->num_relocs--; + numrelocs--; + } } else if (hdr->num_waitchks) { int numwaitchks = (remaining / sizeof(struct nvhost_waitchk)); @@ -274,16 +281,18 @@ static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf, } else if (priv->num_relocshifts) { int next_shift = job->num_relocs - priv->num_relocshifts; - consumed = sizeof(struct nvhost_reloc_shift); - if (remaining < consumed) + int num = + (remaining / sizeof(struct nvhost_reloc_shift)); + if (!num) break; - if (copy_from_user( - &job->pinarray[next_shift].reloc_shift, + num = min_t(int, num, priv->num_relocshifts); + consumed = num * sizeof(struct nvhost_reloc_shift); + if (copy_from_user(&job->relocshiftarray[next_shift], buf, consumed)) { err = -EFAULT; break; } - priv->num_relocshifts--; + priv->num_relocshifts -= num; } else { err = -EFAULT; break; diff --git a/drivers/video/tegra/host/nvhost_job.c b/drivers/video/tegra/host/nvhost_job.c index 6d8c3bd2bd50..e029449b6184 100644 --- a/drivers/video/tegra/host/nvhost_job.c +++ b/drivers/video/tegra/host/nvhost_job.c @@ -41,7 +41,8 @@ static int job_size(struct nvhost_submit_hdr_ext *hdr) int num_unpins = num_cmdbufs + num_relocs; return sizeof(struct nvhost_job) - + num_relocs * sizeof(struct nvmap_pinarray_elem) + + num_relocs * sizeof(struct nvhost_reloc) + + num_relocs * sizeof(struct nvhost_reloc_shift) + num_unpins * sizeof(struct nvmap_handle_ref *) + num_waitchks * sizeof(struct nvhost_waitchk) + num_cmdbufs * sizeof(struct nvhost_job_gather); @@ -63,8 +64,10 @@ static void init_fields(struct nvhost_job *job, /* Redistribute memory to the structs */ mem += sizeof(struct nvhost_job); - job->pinarray = num_relocs ? mem : NULL; - mem += num_relocs * sizeof(struct nvmap_pinarray_elem); + job->relocarray = num_relocs ? mem : NULL; + mem += num_relocs * sizeof(struct nvhost_reloc); + job->relocshiftarray = num_relocs ? mem : NULL; + mem += num_relocs * sizeof(struct nvhost_reloc_shift); job->unpins = num_unpins ? mem : NULL; mem += num_unpins * sizeof(struct nvmap_handle_ref *); job->waitchk = num_waitchks ? mem : NULL; @@ -154,44 +157,46 @@ void nvhost_job_add_gather(struct nvhost_job *job, job->num_gathers += 1; } -static int do_relocs(struct nvhost_job *job, u32 patch_mem, void *patch_addr) +static int do_relocs(struct nvhost_job *job, u32 cmdbuf_mem, void *cmdbuf_addr) { - phys_addr_t pin_phys; + phys_addr_t target_phys; int i; u32 mem_id = 0; - struct nvmap_handle_ref *pin_ref = NULL; + struct nvmap_handle_ref *target_ref = NULL; /* pin & patch the relocs for one gather */ for (i = 0; i < job->num_relocs; i++) { - struct nvmap_pinarray_elem *pin = &job->pinarray[i]; + struct nvhost_reloc *reloc = &job->relocarray[i]; + struct nvhost_reloc_shift *shift = &job->relocshiftarray[i]; /* skip all other gathers */ - if (patch_mem != pin->patch_mem) + if (cmdbuf_mem != reloc->cmdbuf_mem) continue; /* check if pin-mem is same as previous */ - if (pin->pin_mem != mem_id) { - pin_ref = nvmap_duplicate_handle_id(job->nvmap, - pin->pin_mem); - if (IS_ERR(pin_ref)) - return PTR_ERR(pin_ref); - - pin_phys = nvmap_pin(job->nvmap, pin_ref); - if (IS_ERR((void *)pin_phys)) { - nvmap_free(job->nvmap, pin_ref); - return pin_phys; + if (reloc->target != mem_id) { + target_ref = nvmap_duplicate_handle_id(job->nvmap, + reloc->target); + if (IS_ERR(target_ref)) + return PTR_ERR(target_ref); + + target_phys = nvmap_pin(job->nvmap, target_ref); + if (IS_ERR((void *)target_phys)) { + nvmap_free(job->nvmap, target_ref); + return target_phys; } - mem_id = pin->pin_mem; - job->unpins[job->num_unpins++] = pin_ref; + mem_id = reloc->target; + job->unpins[job->num_unpins++] = target_ref; } - __raw_writel((pin_phys + pin->pin_offset) >> pin->reloc_shift, - (patch_addr + pin->patch_offset)); + __raw_writel( + (target_phys + reloc->target_offset) >> shift->shift, + (cmdbuf_addr + reloc->cmdbuf_offset)); /* Different gathers might have same mem_id. This ensures we * perform reloc only once per gather memid. */ - pin->patch_mem = 0; + reloc->cmdbuf_mem = 0; } return 0; @@ -216,7 +221,8 @@ static int do_waitchks(struct nvhost_job *job, struct nvhost_syncpt *sp, continue; trace_nvhost_syncpt_wait_check(wait->mem, wait->offset, - wait->syncpt_id, wait->thresh); + wait->syncpt_id, wait->thresh, + nvhost_syncpt_read(sp, wait->syncpt_id)); if (nvhost_syncpt_is_expired(sp, wait->syncpt_id, wait->thresh)) { /* diff --git a/drivers/video/tegra/host/nvhost_job.h b/drivers/video/tegra/host/nvhost_job.h index b30f5faf7e8f..ec1366337279 100644 --- a/drivers/video/tegra/host/nvhost_job.h +++ b/drivers/video/tegra/host/nvhost_job.h @@ -67,7 +67,8 @@ struct nvhost_job { u32 waitchk_mask; /* Array of handles to be pinned & unpinned */ - struct nvmap_pinarray_elem *pinarray; + struct nvhost_reloc *relocarray; + struct nvhost_reloc_shift *relocshiftarray; int num_relocs; struct nvmap_handle_ref **unpins; int num_unpins; -- cgit v1.2.3