11c248b7dSInki Dae /* exynos_drm_gem.h 21c248b7dSInki Dae * 31c248b7dSInki Dae * Copyright (c) 2011 Samsung Electronics Co., Ltd. 41c248b7dSInki Dae * Authoer: Inki Dae <inki.dae@samsung.com> 51c248b7dSInki Dae * 6d81aecb5SInki Dae * This program is free software; you can redistribute it and/or modify it 7d81aecb5SInki Dae * under the terms of the GNU General Public License as published by the 8d81aecb5SInki Dae * Free Software Foundation; either version 2 of the License, or (at your 9d81aecb5SInki Dae * option) any later version. 101c248b7dSInki Dae */ 111c248b7dSInki Dae 121c248b7dSInki Dae #ifndef _EXYNOS_DRM_GEM_H_ 131c248b7dSInki Dae #define _EXYNOS_DRM_GEM_H_ 141c248b7dSInki Dae 151c248b7dSInki Dae #define to_exynos_gem_obj(x) container_of(x,\ 161c248b7dSInki Dae struct exynos_drm_gem_obj, base) 171c248b7dSInki Dae 18dcf9af82SInki Dae #define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG) 19dcf9af82SInki Dae 201c248b7dSInki Dae /* 212c871127SInki Dae * exynos drm gem buffer structure. 222c871127SInki Dae * 232c871127SInki Dae * @kvaddr: kernel virtual address to allocated memory region. 242a3098ffSInki Dae * *userptr: user space address. 252c871127SInki Dae * @dma_addr: bus address(accessed by dma) to allocated memory region. 262c871127SInki Dae * - this address could be physical address without IOMMU and 272c871127SInki Dae * device address with IOMMU. 282a3098ffSInki Dae * @write: whether pages will be written to by the caller. 294744ad24SInki Dae * @pages: Array of backing pages. 302b35892eSInki Dae * @sgt: sg table to transfer page data. 312c871127SInki Dae * @size: size of allocated memory region. 322a3098ffSInki Dae * @pfnmap: indicate whether memory region from userptr is mmaped with 332a3098ffSInki Dae * VM_PFNMAP or not. 342c871127SInki Dae */ 352c871127SInki Dae struct exynos_drm_gem_buf { 362c871127SInki Dae void __iomem *kvaddr; 372a3098ffSInki Dae unsigned long userptr; 382c871127SInki Dae dma_addr_t dma_addr; 390519f9a1SInki Dae struct dma_attrs dma_attrs; 402a3098ffSInki Dae unsigned int write; 414744ad24SInki Dae struct page **pages; 422b35892eSInki Dae struct sg_table *sgt; 432c871127SInki Dae unsigned long size; 442a3098ffSInki Dae bool pfnmap; 452c871127SInki Dae }; 462c871127SInki Dae 472c871127SInki Dae /* 481c248b7dSInki Dae * exynos drm buffer structure. 491c248b7dSInki Dae * 501c248b7dSInki Dae * @base: a gem object. 511c248b7dSInki Dae * - a new handle to this gem object would be created 521c248b7dSInki Dae * by drm_gem_handle_create(). 532c871127SInki Dae * @buffer: a pointer to exynos_drm_gem_buffer object. 542c871127SInki Dae * - contain the information to memory region allocated 552c871127SInki Dae * by user request or at framebuffer creation. 561c248b7dSInki Dae * continuous memory region allocated by user request 571c248b7dSInki Dae * or at framebuffer creation. 583c52b880SInki Dae * @size: size requested from user, in bytes and this size is aligned 593c52b880SInki Dae * in page unit. 602a3098ffSInki Dae * @vma: a pointer to vm_area. 612b35892eSInki Dae * @flags: indicate memory type to allocated buffer and cache attruibute. 621c248b7dSInki Dae * 63*c6b78bc8SMasanari Iida * P.S. this object would be transferred to user as kms_bo.handle so 641c248b7dSInki Dae * user can access the buffer through kms_bo.handle. 651c248b7dSInki Dae */ 661c248b7dSInki Dae struct exynos_drm_gem_obj { 671c248b7dSInki Dae struct drm_gem_object base; 682c871127SInki Dae struct exynos_drm_gem_buf *buffer; 692b35892eSInki Dae unsigned long size; 702a3098ffSInki Dae struct vm_area_struct *vma; 712b35892eSInki Dae unsigned int flags; 721c248b7dSInki Dae }; 731c248b7dSInki Dae 74b2df26c1SInki Dae struct page **exynos_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); 75b2df26c1SInki Dae 762364839aSJoonyoung Shim /* destroy a buffer with gem object */ 772364839aSJoonyoung Shim void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj); 782364839aSJoonyoung Shim 79b2df26c1SInki Dae /* create a private gem object and initialize it. */ 80b2df26c1SInki Dae struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, 81b2df26c1SInki Dae unsigned long size); 82b2df26c1SInki Dae 832364839aSJoonyoung Shim /* create a new buffer with gem object */ 84f088d5a9SInki Dae struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, 852b35892eSInki Dae unsigned int flags, 86ee5e770eSJoonyoung Shim unsigned long size); 871c248b7dSInki Dae 881c248b7dSInki Dae /* 891c248b7dSInki Dae * request gem object creation and buffer allocation as the size 901c248b7dSInki Dae * that it is calculated with framebuffer information such as width, 911c248b7dSInki Dae * height and bpp. 921c248b7dSInki Dae */ 931c248b7dSInki Dae int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, 941c248b7dSInki Dae struct drm_file *file_priv); 951c248b7dSInki Dae 96f0b1bda7SInki Dae /* 97f0b1bda7SInki Dae * get dma address from gem handle and this function could be used for 98f0b1bda7SInki Dae * other drivers such as 2d/3d acceleration drivers. 99f0b1bda7SInki Dae * with this function call, gem object reference count would be increased. 100f0b1bda7SInki Dae */ 101d87342c1SInki Dae dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev, 102f0b1bda7SInki Dae unsigned int gem_handle, 103d87342c1SInki Dae struct drm_file *filp); 104f0b1bda7SInki Dae 105f0b1bda7SInki Dae /* 106f0b1bda7SInki Dae * put dma address from gem handle and this function could be used for 107f0b1bda7SInki Dae * other drivers such as 2d/3d acceleration drivers. 108f0b1bda7SInki Dae * with this function call, gem object reference count would be decreased. 109f0b1bda7SInki Dae */ 110f0b1bda7SInki Dae void exynos_drm_gem_put_dma_addr(struct drm_device *dev, 111f0b1bda7SInki Dae unsigned int gem_handle, 112d87342c1SInki Dae struct drm_file *filp); 113f0b1bda7SInki Dae 1141c248b7dSInki Dae /* get buffer offset to map to user space. */ 1151c248b7dSInki Dae int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data, 1161c248b7dSInki Dae struct drm_file *file_priv); 1171c248b7dSInki Dae 118ee5e770eSJoonyoung Shim /* 119ee5e770eSJoonyoung Shim * mmap the physically continuous memory that a gem object contains 120ee5e770eSJoonyoung Shim * to user space. 121ee5e770eSJoonyoung Shim */ 122ee5e770eSJoonyoung Shim int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, 1231c248b7dSInki Dae struct drm_file *file_priv); 1241c248b7dSInki Dae 1252a3098ffSInki Dae /* map user space allocated by malloc to pages. */ 1262a3098ffSInki Dae int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data, 1272a3098ffSInki Dae struct drm_file *file_priv); 1282a3098ffSInki Dae 12940cd7e0cSInki Dae /* get buffer information to memory region allocated by gem. */ 13040cd7e0cSInki Dae int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, 13140cd7e0cSInki Dae struct drm_file *file_priv); 13240cd7e0cSInki Dae 133a4f19aaaSInki Dae /* get buffer size to gem handle. */ 134a4f19aaaSInki Dae unsigned long exynos_drm_gem_get_size(struct drm_device *dev, 135a4f19aaaSInki Dae unsigned int gem_handle, 136a4f19aaaSInki Dae struct drm_file *file_priv); 137a4f19aaaSInki Dae 1381c248b7dSInki Dae /* initialize gem object. */ 1391c248b7dSInki Dae int exynos_drm_gem_init_object(struct drm_gem_object *obj); 1401c248b7dSInki Dae 1411c248b7dSInki Dae /* free gem object. */ 1421c248b7dSInki Dae void exynos_drm_gem_free_object(struct drm_gem_object *gem_obj); 1431c248b7dSInki Dae 1441c248b7dSInki Dae /* create memory region for drm framebuffer. */ 1451c248b7dSInki Dae int exynos_drm_gem_dumb_create(struct drm_file *file_priv, 146ee5e770eSJoonyoung Shim struct drm_device *dev, 147ee5e770eSJoonyoung Shim struct drm_mode_create_dumb *args); 1481c248b7dSInki Dae 1491c248b7dSInki Dae /* map memory region for drm framebuffer to user space. */ 1501c248b7dSInki Dae int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv, 151ee5e770eSJoonyoung Shim struct drm_device *dev, uint32_t handle, 152ee5e770eSJoonyoung Shim uint64_t *offset); 1531c248b7dSInki Dae 154ee5e770eSJoonyoung Shim /* page fault handler and mmap fault address(virtual) to physical memory. */ 155ee5e770eSJoonyoung Shim int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 156ee5e770eSJoonyoung Shim 157ee5e770eSJoonyoung Shim /* set vm_flags and we can change the vm attribute to other one at here. */ 158ee5e770eSJoonyoung Shim int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); 1591c248b7dSInki Dae 1602a3098ffSInki Dae static inline int vma_is_io(struct vm_area_struct *vma) 1612a3098ffSInki Dae { 1622a3098ffSInki Dae return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); 1632a3098ffSInki Dae } 1642a3098ffSInki Dae 1652a3098ffSInki Dae /* get a copy of a virtual memory region. */ 1662a3098ffSInki Dae struct vm_area_struct *exynos_gem_get_vma(struct vm_area_struct *vma); 1672a3098ffSInki Dae 1682a3098ffSInki Dae /* release a userspace virtual memory area. */ 1692a3098ffSInki Dae void exynos_gem_put_vma(struct vm_area_struct *vma); 1702a3098ffSInki Dae 1712a3098ffSInki Dae /* get pages from user space. */ 1722a3098ffSInki Dae int exynos_gem_get_pages_from_userptr(unsigned long start, 1732a3098ffSInki Dae unsigned int npages, 1742a3098ffSInki Dae struct page **pages, 1752a3098ffSInki Dae struct vm_area_struct *vma); 1762a3098ffSInki Dae 1772a3098ffSInki Dae /* drop the reference to pages. */ 1782a3098ffSInki Dae void exynos_gem_put_pages_to_userptr(struct page **pages, 1792a3098ffSInki Dae unsigned int npages, 1802a3098ffSInki Dae struct vm_area_struct *vma); 1812a3098ffSInki Dae 1822a3098ffSInki Dae /* map sgt with dma region. */ 1832a3098ffSInki Dae int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev, 1842a3098ffSInki Dae struct sg_table *sgt, 1852a3098ffSInki Dae enum dma_data_direction dir); 1862a3098ffSInki Dae 1872a3098ffSInki Dae /* unmap sgt from dma region. */ 1882a3098ffSInki Dae void exynos_gem_unmap_sgt_from_dma(struct drm_device *drm_dev, 1892a3098ffSInki Dae struct sg_table *sgt, 1902a3098ffSInki Dae enum dma_data_direction dir); 1912a3098ffSInki Dae 1921c248b7dSInki Dae #endif 193