| /* include/media/videobuf2-ion.h |
| * |
| * Copyright 2011-2012 Samsung Electronics Co., Ltd. |
| * http://www.samsung.com/ |
| * |
| * Definition of Android ION memory allocator for videobuf2 |
| * |
| * 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. |
| */ |
| |
| #ifndef _MEDIA_VIDEOBUF2_ION_H |
| #define _MEDIA_VIDEOBUF2_ION_H |
| |
| #include <linux/scatterlist.h> |
| #include <linux/dma-mapping.h> |
| #include <linux/ion.h> |
| #include <linux/exynos_ion.h> |
| #include <linux/err.h> |
| |
| /* flags to vb2_ion_create_context |
| * These flags are dependet upon heap flags in ION. |
| * |
| * bit 0 ~ ION_NUM_HEAPS: ion heap flags |
| * bit ION_NUM_HEAPS+1 ~ 20: non-ion flags (cached, iommu) |
| * bit 21 ~ BITS_PER_INT - 1: ion specific flags |
| */ |
| |
| /* Allocate virtually contiguous memory */ |
| #define VB2ION_CTX_VMCONTIG ION_HEAP_SYSTEM_MASK |
| /* Provide device a virtual address space */ |
| #define VB2ION_CTX_IOMMU (1 << (ION_NUM_HEAPS + 1)) |
| /* Non-cached mapping to user when mmap */ |
| #define VB2ION_CTX_UNCACHED (1 << (ION_NUM_HEAPS + 2)) |
| /* DMA of the client device is coherent with CPU */ |
| #define VB2ION_CTX_COHERENT_DMA (1 << (ION_NUM_HEAPS + 3)) |
| /* DMA should read from memory instead of CPU cache even if DMA is coherent */ |
| #define VB2ION_CTX_UNCACHED_READ_DMA (1 << (ION_NUM_HEAPS + 4)) |
| |
| /* flags for contents protection */ |
| #define VB2ION_CTX_DRM_MFCSH (EXYNOS_ION_HEAP_EXYNOS_CONTIG_MASK | \ |
| ION_EXYNOS_MFC_SH_MASK) |
| #define VB2ION_CTX_DRM_VIDEO (EXYNOS_ION_HEAP_EXYNOS_CONTIG_MASK | \ |
| ION_EXYNOS_MFC_OUTPUT_MASK) |
| #define VB2ION_CTX_DRM_MFCFW (EXYNOS_ION_HEAP_EXYNOS_CONTIG_MASK | \ |
| ION_EXYNOS_MFC_FW_MASK) |
| #define VB2ION_CTX_DRM_MFCNFW (EXYNOS_ION_HEAP_EXYNOS_CONTIG_MASK | \ |
| ION_EXYNOS_MFC_NFW_MASK) |
| |
| #define VB2ION_CONTIG_ID_NUM 16 |
| #define VB2ION_NUM_HEAPS 8 |
| /* below 6 is the above vb2-ion flags (ION_NUM_HEAPS + 1 ~ 6) */ |
| #if (BITS_PER_INT <= (VB2ION_CONTIG_ID_NUM + VB2ION_NUM_HEAPS + 6)) |
| #error "Bits are too small to express all flags" |
| #endif |
| |
| #define VB2ION_CTX_MASK_ION_HEAP ((1 << VB2ION_NUM_HEAPS) - 1) |
| #define VB2ION_CTX_MASK_ION_FLAG ~((1 << (BITS_PER_INT - \ |
| VB2ION_CONTIG_ID_NUM)) - 1) |
| /* mask out all non-ion flags */ |
| #define ion_heapflag(flag) (flag & VB2ION_CTX_MASK_ION_HEAP) |
| #define ion_flag(flag) (flag & VB2ION_CTX_MASK_ION_FLAG) |
| |
| struct device; |
| struct vb2_buffer; |
| |
| /* vb2_ion_create_context - create a new vb2 context for buffer manipulation |
| * dev - device that needs to use vb2 |
| * alignment - minimum alignment requirement for the start address of the |
| * allocated buffer from vb2. |
| * flags - detailed control to the vb2 context. See above flags that stats |
| * with VB2ION_* |
| * |
| * This function creates a new videobuf2 context which is internal data of |
| * videobuf2 for allocating and manipulating buffers. Drivers that obtain vb2 |
| * contexts must regard the contexts as keys for videobuf2 to access the |
| * requirments of the drivers for the buffers allocated from videobuf2. |
| * |
| * Once a driver obtains vb2 contexts from vb2_ion_create_context(), it must |
| * assign those contexts to alloc_ctxs[] argument of vb2_ops.queue_setup(). |
| * |
| * Some specifications of a vb2 context can be changed after it has been created |
| * and assigned to vb2 core with vb2_ops.queue_setup(): |
| * - vb2_ion_set_cached(): Changes cached attribute of the buffer which will be |
| * allocated after calling this function. Cached attribute of a buffer is |
| * effected when it is mapped to user with mmap() function call. |
| * - vb2_ion_set_noncoherent_dma_read(): Forces the DMA to read from system |
| * memory even though it is capable of snooping CPU caches. |
| * - vb2_ion_set_alignment(): Changes alignment requirement of the buffer which |
| * will be allocated after calling this function. |
| * |
| * For the devices that needs internal buffers for firmwares or devices' |
| * context buffers, their drivers can generate a vb2 context which is not |
| * handled by vb2 core but only by vb2-ion. |
| * That kinds of vb2 contexts can be passed to the first parameter of |
| * vb2_ion_private_alloc(void *alloc_ctx, size_t size). |
| * |
| * Drivers can generate vb2 contexts as many as they require with different |
| * requirements specified in flags argument. The only _restriction_ on |
| * generating a vb2 context is that the drivers must call |
| * vb2_ion_create_context() in a kernel thread due to the behavior of |
| * ion_client_create(). |
| */ |
| void *vb2_ion_create_context(struct device *dev, size_t alignment, long flags); |
| |
| /* vb2_ion_destroy_context - destroys a vb2 context |
| * This function removes the given vb2 context which is created by |
| * vb2_ion_create_context() |
| */ |
| void vb2_ion_destroy_context(void *ctx); |
| |
| void vb2_ion_set_cached(void *ctx, bool cached); |
| void vb2_ion_set_noncoherent_dma_read(void *ctx, bool noncoherent); |
| int vb2_ion_set_alignment(void *ctx, size_t alignment); |
| |
| /* Data type of the cookie returned by vb2_plane_cookie() function call. |
| * The drivers do not need the definition of this structure. The only reason |
| * why it is defined outside of videobuf2-ion.c is to make some functions |
| * inline. |
| */ |
| struct vb2_ion_cookie { |
| dma_addr_t ioaddr; |
| dma_addr_t paddr; |
| struct sg_table *sgt; |
| off_t offset; |
| }; |
| |
| /* vb2_ion_buffer_offset - return the mapped offset of the buffer |
| * - cookie: pointer returned by vb2_plane_cookie() |
| * |
| * Returns offset value that the mapping starts from. |
| */ |
| |
| static inline off_t vb2_ion_buffer_offset(void *cookie) |
| { |
| return IS_ERR_OR_NULL(cookie) ? |
| -EINVAL : ((struct vb2_ion_cookie *)cookie)->offset; |
| } |
| |
| /* vb2_ion_phys_address - returns the physical address of the given buffer |
| * - cookie: pointer returned by vb2_plane_cookie() |
| * - phys_addr: pointer to the store of the physical address of the buffer |
| * specified by cookie. |
| * |
| * Returns -EINVAL if the buffer does not have nor physically contiguous memory. |
| */ |
| static inline int vb2_ion_phys_address(void *cookie, phys_addr_t *phys_addr) |
| { |
| struct vb2_ion_cookie *vb2cookie = cookie; |
| |
| if (WARN_ON(!phys_addr || IS_ERR_OR_NULL(cookie))) |
| return -EINVAL; |
| |
| if (vb2cookie->paddr) { |
| *phys_addr = vb2cookie->paddr; |
| } else { |
| if (vb2cookie->sgt && vb2cookie->sgt->nents == 1) { |
| *phys_addr = sg_phys(vb2cookie->sgt->sgl) + |
| vb2cookie->offset; |
| } else { |
| *phys_addr = 0; |
| return -EINVAL; |
| } |
| } |
| |
| return 0; |
| } |
| |
| /* vb2_ion_dma_address - returns the DMA address that device can see |
| * - cookie: pointer returned by vb2_plane_cookie() |
| * - dma_addr: pointer to the store of the address of the buffer specified |
| * by cookie. It can be either IO virtual address or physical address |
| * depending on the specification of allocation context which allocated |
| * the buffer. |
| * |
| * Returns -EINVAL if the buffer has neither IO virtual address nor physically |
| * contiguous memory |
| */ |
| static inline int vb2_ion_dma_address(void *cookie, dma_addr_t *dma_addr) |
| { |
| struct vb2_ion_cookie *vb2cookie = cookie; |
| |
| if (WARN_ON(!dma_addr || IS_ERR_OR_NULL(cookie))) |
| return -EINVAL; |
| |
| if (vb2cookie->ioaddr == 0) |
| return vb2_ion_phys_address(cookie, (phys_addr_t *)dma_addr); |
| |
| *dma_addr = vb2cookie->ioaddr; |
| |
| return 0; |
| } |
| |
| /* vb2_ion_get_sg - returns scatterlist of the given cookie. |
| * - cookie: pointer returned by vb2_plane_cookie() |
| * - nents: pointer to the store of number of elements in the returned |
| * scatterlist |
| * |
| * Returns the scatterlist of the buffer specified by cookie. |
| * If the arguments are not correct, returns NULL. |
| */ |
| static inline struct scatterlist *vb2_ion_get_sg(void *cookie, int *nents) |
| { |
| struct vb2_ion_cookie *vb2cookie = cookie; |
| |
| if (WARN_ON(!nents || IS_ERR_OR_NULL(cookie))) |
| return NULL; |
| |
| *nents = vb2cookie->sgt->nents; |
| return vb2cookie->sgt->sgl; |
| } |
| |
| /***** Device's internal/context buffer support *****/ |
| |
| /* vb2_ion_private_vaddr - the kernelspace address for the given cookie |
| * cookie - pointer returned by vb2_ion_private_alloc() |
| * |
| * This function returns minus error value on error. |
| */ |
| void *vb2_ion_private_vaddr(void *cookie); |
| |
| /* vb2_ion_private_alloc - allocate a buffer for device drivers's private use |
| * alloc_ctx - pointer returned by vb2_ion_create_context |
| * size - size of the buffer allocated |
| * |
| * This function returns the pointer to a cookie that represents the allocated |
| * buffer or minus error value. With the cookie you can: |
| * - retrieve scatterlist of the buffer. |
| * - retrieve dma address. (IO virutal address if IOMMU is enabled when |
| * creating alloc_ctx or physical address) |
| * - retrieve virtual address in the kernel space. |
| * - free the allocated buffer |
| */ |
| void *vb2_ion_private_alloc(void *alloc_ctx, size_t size); |
| |
| /* vb2_ion_private_free - free the buffer allocated by vb2_ion_private_alloc */ |
| void vb2_ion_private_free(void *cookie); |
| |
| /***** Cache mainatenance operations *****/ |
| void vb2_ion_sync_for_device(void *cookie, off_t offset, size_t size, |
| enum dma_data_direction dir); |
| void vb2_ion_sync_for_cpu(void *cookie, off_t offset, size_t size, |
| enum dma_data_direction dir); |
| int vb2_ion_buf_prepare(struct vb2_buffer *vb); |
| void vb2_ion_buf_finish(struct vb2_buffer *vb); |
| int vb2_ion_buf_prepare_exact(struct vb2_buffer *vb); |
| int vb2_ion_buf_finish_exact(struct vb2_buffer *vb); |
| |
| /* IOMMU support */ |
| |
| /* vb2_ion_attach_iommu - enables IOMMU of the device specified in alloc_ctx */ |
| int vb2_ion_attach_iommu(void *alloc_ctx); |
| |
| /* vb2_ion_attach_iommu - disables IOMMU of the device specified in alloc_ctx */ |
| void vb2_ion_detach_iommu(void *alloc_ctx); |
| |
| extern const struct vb2_mem_ops vb2_ion_memops; |
| |
| #endif /* _MEDIA_VIDEOBUF2_ION_H */ |