summaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h')
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h323
1 files changed, 323 insertions, 0 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h
new file mode 100644
index 0000000..dffd6e9
--- /dev/null
+++ b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h
@@ -0,0 +1,323 @@
+/*
+ * Support for Medifield PNW Camera Imaging ISP subsystem.
+ *
+ * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
+ *
+ * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __HMM_BO_H__
+#define __HMM_BO_H__
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include "mmu/isp_mmu.h"
+#include "hmm/hmm_common.h"
+#include "ia_css_types.h"
+
+#define check_bodev_null_return(bdev, exp) \
+ check_null_return(bdev, exp, \
+ "NULL hmm_bo_device.\n")
+
+#define check_bodev_null_return_void(bdev) \
+ check_null_return_void(bdev, \
+ "NULL hmm_bo_device.\n")
+
+#define check_bo_status_yes_goto(bo, _status, label) \
+ var_not_equal_goto((bo->status & (_status)), (_status), \
+ label, \
+ "HMM buffer status not contain %s.\n", \
+ #_status)
+
+#define check_bo_status_no_goto(bo, _status, label) \
+ var_equal_goto((bo->status & (_status)), (_status), \
+ label, \
+ "HMM buffer status contains %s.\n", \
+ #_status)
+
+#define rbtree_node_to_hmm_bo(root_node) \
+ container_of((root_node), struct hmm_buffer_object, node)
+
+#define list_to_hmm_bo(list_ptr) \
+ list_entry((list_ptr), struct hmm_buffer_object, list)
+
+#define kref_to_hmm_bo(kref_ptr) \
+ list_entry((kref_ptr), struct hmm_buffer_object, kref)
+
+#define check_bo_null_return(bo, exp) \
+ check_null_return(bo, exp, "NULL hmm buffer object.\n")
+
+#define check_bo_null_return_void(bo) \
+ check_null_return_void(bo, "NULL hmm buffer object.\n")
+
+#define HMM_MAX_ORDER 3
+#define HMM_MIN_ORDER 0
+
+#define ISP_VM_START 0x0
+#define ISP_VM_SIZE (0x7FFFFFFF) /* 2G address space */
+#define ISP_PTR_NULL NULL
+
+#define HMM_BO_DEVICE_INITED 0x1
+
+enum hmm_bo_type {
+ HMM_BO_PRIVATE,
+ HMM_BO_SHARE,
+ HMM_BO_USER,
+#ifdef CONFIG_ION
+ HMM_BO_ION,
+#endif
+ HMM_BO_LAST,
+};
+
+enum hmm_page_type {
+ HMM_PAGE_TYPE_RESERVED,
+ HMM_PAGE_TYPE_DYNAMIC,
+ HMM_PAGE_TYPE_GENERAL,
+};
+
+#define HMM_BO_MASK 0x1
+#define HMM_BO_FREE 0x0
+#define HMM_BO_ALLOCED 0x1
+#define HMM_BO_PAGE_ALLOCED 0x2
+#define HMM_BO_BINDED 0x4
+#define HMM_BO_MMAPED 0x8
+#define HMM_BO_VMAPED 0x10
+#define HMM_BO_VMAPED_CACHED 0x20
+#define HMM_BO_ACTIVE 0x1000
+#define HMM_BO_MEM_TYPE_USER 0x1
+#define HMM_BO_MEM_TYPE_PFN 0x2
+
+struct hmm_bo_device {
+ struct isp_mmu mmu;
+
+ /* start/pgnr/size is used to record the virtual memory of this bo */
+ unsigned int start;
+ unsigned int pgnr;
+ unsigned int size;
+
+ /* list lock is used to protect the entire_bo_list */
+ spinlock_t list_lock;
+#ifdef CONFIG_ION
+ struct ion_client *iclient;
+#endif
+ int flag;
+
+ /* linked list for entire buffer object */
+ struct list_head entire_bo_list;
+ /* rbtree for maintain entire allocated vm */
+ struct rb_root allocated_rbtree;
+ /* rbtree for maintain entire free vm */
+ struct rb_root free_rbtree;
+ struct mutex rbtree_mutex;
+ struct kmem_cache *bo_cache;
+};
+
+struct hmm_page_object {
+ struct page *page;
+ enum hmm_page_type type;
+};
+
+struct hmm_buffer_object {
+ struct hmm_bo_device *bdev;
+ struct list_head list;
+ struct kref kref;
+
+ /* mutex protecting this BO */
+ struct mutex mutex;
+ enum hmm_bo_type type;
+ struct hmm_page_object *page_obj; /* physical pages */
+ int from_highmem;
+ int mmap_count;
+#ifdef CONFIG_ION
+ struct ion_handle *ihandle;
+#endif
+ int status;
+ int mem_type;
+ void *vmap_addr; /* kernel virtual address by vmap */
+
+ struct rb_node node;
+ unsigned int start;
+ unsigned int end;
+ unsigned int pgnr;
+ /*
+ * When insert a bo which has the same pgnr with an existed
+ * bo node in the free_rbtree, using "prev & next" pointer
+ * to maintain a bo linked list instead of insert this bo
+ * into free_rbtree directly, it will make sure each node
+ * in free_rbtree has different pgnr.
+ * "prev & next" default is NULL.
+ */
+ struct hmm_buffer_object *prev;
+ struct hmm_buffer_object *next;
+};
+
+struct hmm_buffer_object *hmm_bo_alloc(struct hmm_bo_device *bdev,
+ unsigned int pgnr);
+
+void hmm_bo_release(struct hmm_buffer_object *bo);
+
+int hmm_bo_device_init(struct hmm_bo_device *bdev,
+ struct isp_mmu_client *mmu_driver,
+ unsigned int vaddr_start, unsigned int size);
+
+/*
+ * clean up all hmm_bo_device related things.
+ */
+void hmm_bo_device_exit(struct hmm_bo_device *bdev);
+
+/*
+ * whether the bo device is inited or not.
+ */
+int hmm_bo_device_inited(struct hmm_bo_device *bdev);
+
+/*
+ * increse buffer object reference.
+ */
+void hmm_bo_ref(struct hmm_buffer_object *bo);
+
+/*
+ * decrese buffer object reference. if reference reaches 0,
+ * release function of the buffer object will be called.
+ *
+ * this call is also used to release hmm_buffer_object or its
+ * upper level object with it embedded in. you need to call
+ * this function when it is no longer used.
+ *
+ * Note:
+ *
+ * user dont need to care about internal resource release of
+ * the buffer object in the release callback, it will be
+ * handled internally.
+ *
+ * this call will only release internal resource of the buffer
+ * object but will not free the buffer object itself, as the
+ * buffer object can be both pre-allocated statically or
+ * dynamically allocated. so user need to deal with the release
+ * of the buffer object itself manually. below example shows
+ * the normal case of using the buffer object.
+ *
+ * struct hmm_buffer_object *bo = hmm_bo_create(bdev, pgnr);
+ * ......
+ * hmm_bo_unref(bo);
+ *
+ * or:
+ *
+ * struct hmm_buffer_object bo;
+ *
+ * hmm_bo_init(bdev, &bo, pgnr, NULL);
+ * ...
+ * hmm_bo_unref(&bo);
+ */
+void hmm_bo_unref(struct hmm_buffer_object *bo);
+
+
+/*
+ * allocate/free physical pages for the bo. will try to alloc mem
+ * from highmem if from_highmem is set, and type indicate that the
+ * pages will be allocated by using video driver (for share buffer)
+ * or by ISP driver itself.
+ */
+
+
+int hmm_bo_allocated(struct hmm_buffer_object *bo);
+
+
+/*
+ * allocate/free physical pages for the bo. will try to alloc mem
+ * from highmem if from_highmem is set, and type indicate that the
+ * pages will be allocated by using video driver (for share buffer)
+ * or by ISP driver itself.
+ */
+int hmm_bo_alloc_pages(struct hmm_buffer_object *bo,
+ enum hmm_bo_type type, int from_highmem,
+ void *userptr, bool cached);
+void hmm_bo_free_pages(struct hmm_buffer_object *bo);
+int hmm_bo_page_allocated(struct hmm_buffer_object *bo);
+
+/*
+ * get physical page info of the bo.
+ */
+int hmm_bo_get_page_info(struct hmm_buffer_object *bo,
+ struct hmm_page_object **page_obj, int *pgnr);
+
+/*
+ * bind/unbind the physical pages to a virtual address space.
+ */
+int hmm_bo_bind(struct hmm_buffer_object *bo);
+void hmm_bo_unbind(struct hmm_buffer_object *bo);
+int hmm_bo_binded(struct hmm_buffer_object *bo);
+
+/*
+ * vmap buffer object's pages to contiguous kernel virtual address.
+ * if the buffer has been vmaped, return the virtual address directly.
+ */
+void *hmm_bo_vmap(struct hmm_buffer_object *bo, bool cached);
+
+/*
+ * flush the cache for the vmapped buffer object's pages,
+ * if the buffer has not been vmapped, return directly.
+ */
+void hmm_bo_flush_vmap(struct hmm_buffer_object *bo);
+
+/*
+ * vunmap buffer object's kernel virtual address.
+ */
+void hmm_bo_vunmap(struct hmm_buffer_object *bo);
+
+/*
+ * mmap the bo's physical pages to specific vma.
+ *
+ * vma's address space size must be the same as bo's size,
+ * otherwise it will return -EINVAL.
+ *
+ * vma->vm_flags will be set to (VM_RESERVED | VM_IO).
+ */
+int hmm_bo_mmap(struct vm_area_struct *vma,
+ struct hmm_buffer_object *bo);
+
+extern struct hmm_pool dynamic_pool;
+extern struct hmm_pool reserved_pool;
+
+/*
+ * find the buffer object by its virtual address vaddr.
+ * return NULL if no such buffer object found.
+ */
+struct hmm_buffer_object *hmm_bo_device_search_start(
+ struct hmm_bo_device *bdev, ia_css_ptr vaddr);
+
+/*
+ * find the buffer object by its virtual address.
+ * it does not need to be the start address of one bo,
+ * it can be an address within the range of one bo.
+ * return NULL if no such buffer object found.
+ */
+struct hmm_buffer_object *hmm_bo_device_search_in_range(
+ struct hmm_bo_device *bdev, ia_css_ptr vaddr);
+
+/*
+ * find the buffer object with kernel virtual address vaddr.
+ * return NULL if no such buffer object found.
+ */
+struct hmm_buffer_object *hmm_bo_device_search_vmap_start(
+ struct hmm_bo_device *bdev, const void *vaddr);
+
+
+#endif
OpenPOWER on IntegriCloud