diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
commit | 2c3c1048746a4622d8c89a29670120dc8fab93c4 (patch) | |
tree | 848558de17fb3008cdf4d861b01ac7781903ce39 /drivers/staging/media/atomisp/include/hmm | |
parent | Initial commit. (diff) | |
download | linux-2c3c1048746a4622d8c89a29670120dc8fab93c4.tar.xz linux-2c3c1048746a4622d8c89a29670120dc8fab93c4.zip |
Adding upstream version 6.1.76.upstream/6.1.76upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/staging/media/atomisp/include/hmm')
-rw-r--r-- | drivers/staging/media/atomisp/include/hmm/hmm.h | 80 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/include/hmm/hmm_bo.h | 272 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/include/hmm/hmm_common.h | 71 |
3 files changed, 423 insertions, 0 deletions
diff --git a/drivers/staging/media/atomisp/include/hmm/hmm.h b/drivers/staging/media/atomisp/include/hmm/hmm.h new file mode 100644 index 000000000..c0384bb0a --- /dev/null +++ b/drivers/staging/media/atomisp/include/hmm/hmm.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * 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. + * + * + */ + +#ifndef __HMM_H__ +#define __HMM_H__ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/slab.h> +#include <linux/mm.h> + +#include "hmm_common.h" +#include "hmm/hmm_bo.h" +#include "ia_css_types.h" + +#define mmgr_NULL ((ia_css_ptr)0) +#define mmgr_EXCEPTION ((ia_css_ptr) - 1) + +int hmm_init(void); +void hmm_cleanup(void); + +ia_css_ptr hmm_alloc(size_t bytes); +ia_css_ptr hmm_create_from_userdata(size_t bytes, const void __user *userptr); +void hmm_free(ia_css_ptr ptr); +int hmm_load(ia_css_ptr virt, void *data, unsigned int bytes); +int hmm_store(ia_css_ptr virt, const void *data, unsigned int bytes); +int hmm_set(ia_css_ptr virt, int c, unsigned int bytes); +int hmm_flush(ia_css_ptr virt, unsigned int bytes); + +/* + * get kernel memory physical address from ISP virtual address. + */ +phys_addr_t hmm_virt_to_phys(ia_css_ptr virt); + +/* + * map ISP memory starts with virt to kernel virtual address + * by using vmap. return NULL if failed. + * + * virt must be the start address of ISP memory (return by hmm_alloc), + * do not pass any other address. + */ +void *hmm_vmap(ia_css_ptr virt, bool cached); +void hmm_vunmap(ia_css_ptr virt); + +/* + * flush the cache for the vmapped buffer. + * if the buffer has not been vmapped, return directly. + */ +void hmm_flush_vmap(ia_css_ptr virt); + +/* + * map ISP memory starts with virt to specific vma. + * + * used for mmap operation. + * + * virt must be the start address of ISP memory (return by hmm_alloc), + * do not pass any other address. + */ +int hmm_mmap(struct vm_area_struct *vma, ia_css_ptr virt); + +extern struct hmm_bo_device bo_device; + +#endif diff --git a/drivers/staging/media/atomisp/include/hmm/hmm_bo.h b/drivers/staging/media/atomisp/include/hmm/hmm_bo.h new file mode 100644 index 000000000..c5cbae1d9 --- /dev/null +++ b/drivers/staging/media/atomisp/include/hmm/hmm_bo.h @@ -0,0 +1,272 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * 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. + * + * + */ + +#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 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_USER, + HMM_BO_LAST, +}; + +#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 + +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; + 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_buffer_object { + struct hmm_bo_device *bdev; + struct list_head list; + struct kref kref; + + struct page **pages; + + /* mutex protecting this BO */ + struct mutex mutex; + enum hmm_bo_type type; + int mmap_count; + int status; + 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); + +int hmm_bo_allocated(struct hmm_buffer_object *bo); + +/* + * Allocate/Free physical pages for the bo. Type indicates if 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, + const void __user *userptr); +void hmm_bo_free_pages(struct hmm_buffer_object *bo); +int hmm_bo_page_allocated(struct hmm_buffer_object *bo); + +/* + * 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); + +/* + * 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 diff --git a/drivers/staging/media/atomisp/include/hmm/hmm_common.h b/drivers/staging/media/atomisp/include/hmm/hmm_common.h new file mode 100644 index 000000000..d8610b135 --- /dev/null +++ b/drivers/staging/media/atomisp/include/hmm/hmm_common.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * 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. + * + * + */ + +#ifndef __HMM_BO_COMMON_H__ +#define __HMM_BO_COMMON_H__ + +#define HMM_BO_NAME "HMM" + +/* + * some common use micros + */ +#define var_equal_return(var1, var2, exp, fmt, arg ...) \ + do { \ + if ((var1) == (var2)) { \ + dev_err(atomisp_dev, \ + fmt, ## arg); \ + return exp;\ + } \ + } while (0) + +#define var_equal_return_void(var1, var2, fmt, arg ...) \ + do { \ + if ((var1) == (var2)) { \ + dev_err(atomisp_dev, \ + fmt, ## arg); \ + return;\ + } \ + } while (0) + +#define var_equal_goto(var1, var2, label, fmt, arg ...) \ + do { \ + if ((var1) == (var2)) { \ + dev_err(atomisp_dev, \ + fmt, ## arg); \ + goto label;\ + } \ + } while (0) + +#define var_not_equal_goto(var1, var2, label, fmt, arg ...) \ + do { \ + if ((var1) != (var2)) { \ + dev_err(atomisp_dev, \ + fmt, ## arg); \ + goto label;\ + } \ + } while (0) + +#define check_null_return(ptr, exp, fmt, arg ...) \ + var_equal_return(ptr, NULL, exp, fmt, ## arg) + +#define check_null_return_void(ptr, fmt, arg ...) \ + var_equal_return_void(ptr, NULL, fmt, ## arg) + +#endif |