From b6f12a3449234f9960998954382e1a9afea7764d Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Thu, 24 May 2012 14:18:28 +0300 Subject: video: tegra: nvmap: Remove nvhost specific APIs Remove nvmap_pin_array() and nvmap_patch_word() and their utility functions. Bug 965206 Change-Id: I217a427934b0b99b5252b33ab3ac4eaaa8c7e076 Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/104451 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Mayuresh Kulkarni GVS: Gerrit_Virtual_Submit Reviewed-by: Juha Tukkinen --- drivers/video/tegra/nvmap/nvmap.c | 268 -------------------------------------- include/linux/nvmap.h | 16 --- 2 files changed, 284 deletions(-) diff --git a/drivers/video/tegra/nvmap/nvmap.c b/drivers/video/tegra/nvmap/nvmap.c index a0c4156668e5..b7fd695d04ee 100644 --- a/drivers/video/tegra/nvmap/nvmap.c +++ b/drivers/video/tegra/nvmap/nvmap.c @@ -352,225 +352,6 @@ static phys_addr_t handle_phys(struct nvmap_handle *h) return addr; } -/* stores the physical address (+offset) of each handle relocation entry - * into its output location. see nvmap_pin_array for more details. - * - * each entry in arr (i.e., each relocation request) specifies two handles: - * the handle to pin (pin), and the handle where the address of pin should be - * written (patch). in pseudocode, this loop basically looks like: - * - * for (i = 0; i < nr; i++) { - * (pin, pin_offset, patch, patch_offset) = arr[i]; - * patch[patch_offset] = address_of(pin) + pin_offset; - * } - */ -static int nvmap_reloc_pin_array(struct nvmap_client *client, - const struct nvmap_pinarray_elem *arr, - int nr, struct nvmap_handle *gather) -{ - struct nvmap_handle *last_patch = NULL; - unsigned int last_pfn = 0; - pte_t **pte; - void *addr; - int i; - - pte = nvmap_alloc_pte(client->dev, &addr); - if (IS_ERR(pte)) - return PTR_ERR(pte); - - for (i = 0; i < nr; i++) { - struct nvmap_handle *patch; - struct nvmap_handle *pin; - phys_addr_t reloc_addr; - phys_addr_t phys; - unsigned int pfn; - - /* all of the handles are validated and get'ted prior to - * calling this function, so casting is safe here */ - pin = (struct nvmap_handle *)arr[i].pin_mem; - - if (arr[i].patch_mem == (unsigned long)last_patch) { - patch = last_patch; - } else if (arr[i].patch_mem == (unsigned long)gather) { - patch = gather; - } else { - if (last_patch) - nvmap_handle_put(last_patch); - - patch = nvmap_get_handle_id(client, arr[i].patch_mem); - if (!patch) { - nvmap_free_pte(client->dev, pte); - return -EPERM; - } - last_patch = patch; - } - - if (patch->heap_pgalloc) { - unsigned int page = arr[i].patch_offset >> PAGE_SHIFT; - phys = page_to_phys(patch->pgalloc.pages[page]); - phys += (arr[i].patch_offset & ~PAGE_MASK); - } else { - phys = patch->carveout->base + arr[i].patch_offset; - } - - pfn = __phys_to_pfn(phys); - if (pfn != last_pfn) { - pgprot_t prot = nvmap_pgprot(patch, pgprot_kernel); - phys_addr_t kaddr = (phys_addr_t)addr; - set_pte_at(&init_mm, kaddr, *pte, pfn_pte(pfn, prot)); - flush_tlb_kernel_page(kaddr); - last_pfn = pfn; - } - - reloc_addr = handle_phys(pin) + arr[i].pin_offset; - reloc_addr >>= arr[i].reloc_shift; - __raw_writel(reloc_addr, addr + (phys & ~PAGE_MASK)); - } - - nvmap_free_pte(client->dev, pte); - - if (last_patch) - nvmap_handle_put(last_patch); - - wmb(); - - return 0; -} - -static int nvmap_validate_get_pin_array(struct nvmap_client *client, - const struct nvmap_pinarray_elem *arr, - int nr, struct nvmap_handle **h) -{ - int i; - int ret = 0; - int count = 0; - - nvmap_ref_lock(client); - - for (i = 0; i < nr; i++) { - struct nvmap_handle_ref *ref; - - if (need_resched()) { - nvmap_ref_unlock(client); - schedule(); - nvmap_ref_lock(client); - } - - ref = _nvmap_validate_id_locked(client, arr[i].pin_mem); - - if (!ref) - nvmap_warn(client, "falied to validate id\n"); - else if (!ref->handle) - nvmap_warn(client, "id had no associated handle\n"); - else if (!ref->handle->alloc) - nvmap_warn(client, "handle had no allocation\n"); - - if (!ref || !ref->handle || !ref->handle->alloc) { - ret = -EPERM; - break; - } - - /* a handle may be referenced multiple times in arr, but - * it will only be pinned once; this ensures that the - * minimum number of sync-queue slots in the host driver - * are dedicated to storing unpin lists, which allows - * for greater parallelism between the CPU and graphics - * processor */ - if (ref->handle->flags & NVMAP_HANDLE_VISITED) - continue; - - ref->handle->flags |= NVMAP_HANDLE_VISITED; - - h[count] = nvmap_handle_get(ref->handle); - BUG_ON(!h[count]); - count++; - } - - nvmap_ref_unlock(client); - - if (ret) { - for (i = 0; i < count; i++) { - h[i]->flags &= ~NVMAP_HANDLE_VISITED; - nvmap_handle_put(h[i]); - } - } - - return ret ?: count; -} - -/* a typical mechanism host1x clients use for using the Tegra graphics - * processor is to build a command buffer which contains relocatable - * memory handle commands, and rely on the kernel to convert these in-place - * to addresses which are understood by the GPU hardware. - * - * this is implemented by having clients provide a sideband array - * of relocatable handles (+ offsets) and the location in the command - * buffer handle to patch with the GPU address when the client submits - * its command buffer to the host1x driver. - * - * the host driver also uses this relocation mechanism internally to - * relocate the client's (unpinned) command buffers into host-addressable - * memory. - * - * @client: nvmap_client which should be used for validation; should be - * owned by the process which is submitting command buffers - * @gather: special handle for relocated command buffer outputs used - * internally by the host driver. if this handle is encountered - * as an output handle in the relocation array, it is assumed - * to be a known-good output and is not validated. - * @arr: array of ((relocatable handle, offset), (output handle, offset)) - * tuples. - * @nr: number of entries in arr - * @unique_arr: list of nvmap_handle objects which were pinned by - * nvmap_pin_array. must be unpinned by the caller after the - * command buffers referenced in gather have completed. - */ -int nvmap_pin_array(struct nvmap_client *client, struct nvmap_handle *gather, - const struct nvmap_pinarray_elem *arr, int nr, - struct nvmap_handle **unique_arr) -{ - int count = 0; - int ret = 0; - int i; - - if (mutex_lock_interruptible(&client->share->pin_lock)) { - nvmap_warn(client, "%s interrupted when acquiring pin lock\n", - current->group_leader->comm); - return -EINTR; - } - - count = nvmap_validate_get_pin_array(client, arr, nr, unique_arr); - if (count < 0) { - mutex_unlock(&client->share->pin_lock); - nvmap_warn(client, "failed to validate pin array\n"); - return count; - } - - for (i = 0; i < count; i++) - unique_arr[i]->flags &= ~NVMAP_HANDLE_VISITED; - - ret = wait_pin_array_locked(client, unique_arr, count); - - mutex_unlock(&client->share->pin_lock); - - if (!ret) - ret = nvmap_reloc_pin_array(client, arr, nr, gather); - - if (WARN_ON(ret)) { - for (i = 0; i < count; i++) - nvmap_handle_put(unique_arr[i]); - return ret; - } else { - for (i = 0; i < count; i++) { - if (unique_arr[i]->heap_pgalloc && - unique_arr[i]->pgalloc.dirty) - map_iovmm_area(unique_arr[i]); - } - } - - return count; -} - phys_addr_t nvmap_pin(struct nvmap_client *client, struct nvmap_handle_ref *ref) { @@ -820,52 +601,3 @@ void nvmap_free(struct nvmap_client *client, struct nvmap_handle_ref *r) nvmap_free_handle_id(client, nvmap_ref_to_id(r)); } - -/* - * create a mapping to the user's buffer and write it - * (uses similar logic from nvmap_reloc_pin_array to map the cmdbuf) - */ -int nvmap_patch_word(struct nvmap_client *client, - struct nvmap_handle *patch, - u32 patch_offset, u32 patch_value) -{ - phys_addr_t phys; - unsigned long kaddr; - unsigned int pfn; - void *addr; - pte_t **pte; - pgprot_t prot; - - if (patch_offset >= patch->size) { - nvmap_warn(client, "read/write outside of handle\n"); - return -EFAULT; - } - - pte = nvmap_alloc_pte(client->dev, &addr); - if (IS_ERR(pte)) - return PTR_ERR(pte); - - /* derive physaddr of cmdbuf WAIT to patch */ - if (patch->heap_pgalloc) { - unsigned int page = patch_offset >> PAGE_SHIFT; - phys = page_to_phys(patch->pgalloc.pages[page]); - phys += (patch_offset & ~PAGE_MASK); - } else { - phys = patch->carveout->base + patch_offset; - } - - pfn = __phys_to_pfn(phys); - prot = nvmap_pgprot(patch, pgprot_kernel); - kaddr = (unsigned long)addr; - - /* write PTE, so addr points to cmdbuf PFN */ - set_pte_at(&init_mm, kaddr, *pte, pfn_pte(pfn, prot)); - flush_tlb_kernel_page(kaddr); - - /* write patch_value to addr + page offset */ - __raw_writel(patch_value, addr + (phys & ~PAGE_MASK)); - - nvmap_free_pte(client->dev, pte); - wmb(); - return 0; -} diff --git a/include/linux/nvmap.h b/include/linux/nvmap.h index 60ccdc192df5..553a7bd01a6d 100644 --- a/include/linux/nvmap.h +++ b/include/linux/nvmap.h @@ -92,14 +92,6 @@ struct nvmap_handle_ref { #define nvmap_id_to_handle(_id) ((struct nvmap_handle *)(_id)) -struct nvmap_pinarray_elem { - __u32 patch_mem; - __u32 patch_offset; - __u32 pin_mem; - __u32 pin_offset; - __u32 reloc_shift; -}; - struct nvmap_client *nvmap_create_client(struct nvmap_device *dev, const char *name); @@ -125,17 +117,9 @@ phys_addr_t nvmap_handle_address(struct nvmap_client *c, unsigned long id); void nvmap_unpin(struct nvmap_client *client, struct nvmap_handle_ref *r); -int nvmap_pin_array(struct nvmap_client *client, struct nvmap_handle *gather, - const struct nvmap_pinarray_elem *arr, int nr, - struct nvmap_handle **unique); - void nvmap_unpin_handles(struct nvmap_client *client, struct nvmap_handle **h, int nr); -int nvmap_patch_word(struct nvmap_client *client, - struct nvmap_handle *patch, - u32 patch_offset, u32 patch_value); - struct nvmap_handle_ref *nvmap_duplicate_handle_id(struct nvmap_client *client, unsigned long id); -- cgit v1.2.3