summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/tegra/nvmap/nvmap.c268
-rw-r--r--include/linux/nvmap.h16
2 files changed, 0 insertions, 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);