[COMMON] fimc-is2: Add dual sync settings for 5E9 & OV12A10
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / media / m2m1shot-helper.c
CommitLineData
40d0b6e1 1/*
2 * drivers/media/m2m1shot-helper.c
3 *
4 * Copyright (C) 2014 Samsung Electronics Co., Ltd.
5 *
6 * Contact: Cho KyongHo <pullip.cho@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23#include <linux/kernel.h>
24#include <linux/exynos_iovmm.h>
be5b8a22 25#include <linux/ion_exynos.h>
40d0b6e1 26
27#include <media/m2m1shot-helper.h>
28
29int m2m1shot_map_dma_buf(struct device *dev,
30 struct m2m1shot_buffer_plane_dma *plane,
31 enum dma_data_direction dir)
32{
33 if (plane->dmabuf) {
34 plane->sgt = dma_buf_map_attachment(plane->attachment, dir);
35 if (IS_ERR(plane->sgt)) {
36 dev_err(dev, "%s: failed to map attacment of dma_buf\n",
37 __func__);
38 return PTR_ERR(plane->sgt);
39 }
40d0b6e1 40 }
41
42 return 0;
43}
44EXPORT_SYMBOL(m2m1shot_map_dma_buf);
45
46void m2m1shot_unmap_dma_buf(struct device *dev,
47 struct m2m1shot_buffer_plane_dma *plane,
48 enum dma_data_direction dir)
49{
07e82f1a 50 if (plane->dmabuf)
40d0b6e1 51 dma_buf_unmap_attachment(plane->attachment, plane->sgt, dir);
40d0b6e1 52}
53EXPORT_SYMBOL(m2m1shot_unmap_dma_buf);
54
bf4c54a4
JK
55static inline bool is_dma_coherent(struct device *dev)
56{
57 return device_get_dma_attr(dev) == DEV_DMA_COHERENT;
58}
59
40d0b6e1 60int m2m1shot_dma_addr_map(struct device *dev,
61 struct m2m1shot_buffer_dma *buf,
62 int plane_idx, enum dma_data_direction dir)
63{
64 struct m2m1shot_buffer_plane_dma *plane = &buf->plane[plane_idx];
65 dma_addr_t iova;
bf4c54a4
JK
66 int prot = IOMMU_READ;
67
68 if (dir == DMA_FROM_DEVICE)
69 prot |= IOMMU_WRITE;
70 if (is_dma_coherent(dev))
71 prot |= IOMMU_CACHE;
40d0b6e1 72
73 if (plane->dmabuf) {
74 iova = ion_iovmm_map(plane->attachment, 0,
bf4c54a4 75 plane->bytes_used, dir, prot);
40d0b6e1 76 } else {
07e82f1a
CK
77 down_read(&current->mm->mmap_sem);
78 iova = exynos_iovmm_map_userptr(dev,
79 buf->buffer->plane[plane_idx].userptr,
80 plane->bytes_used, prot);
81 up_read(&current->mm->mmap_sem);
40d0b6e1 82 }
83
84 if (IS_ERR_VALUE(iova))
85 return (int)iova;
86
87 buf->plane[plane_idx].dma_addr = iova + plane->offset;
88
89 return 0;
90}
91
92void m2m1shot_dma_addr_unmap(struct device *dev,
93 struct m2m1shot_buffer_dma *buf, int plane_idx)
94{
95 struct m2m1shot_buffer_plane_dma *plane = &buf->plane[plane_idx];
96 dma_addr_t dma_addr = plane->dma_addr - plane->offset;
97
98 if (plane->dmabuf)
99 ion_iovmm_unmap(plane->attachment, dma_addr);
100 else
07e82f1a 101 exynos_iovmm_unmap_userptr(dev, dma_addr);
40d0b6e1 102
103 plane->dma_addr = 0;
104}
07e82f1a
CK
105
106void m2m1shot_sync_for_device(struct device *dev,
107 struct m2m1shot_buffer_plane_dma *plane,
108 enum dma_data_direction dir)
109{
bf4c54a4
JK
110 if (is_dma_coherent(dev))
111 return;
112
07e82f1a
CK
113 if (plane->dmabuf)
114 dma_sync_sg_for_device(dev, plane->sgt->sgl,
115 plane->sgt->orig_nents, dir);
116 else
117 exynos_iommu_sync_for_device(dev, plane->dma_addr,
118 plane->bytes_used, dir);
119}
120EXPORT_SYMBOL(m2m1shot_sync_for_device);
121
122void m2m1shot_sync_for_cpu(struct device *dev,
123 struct m2m1shot_buffer_plane_dma *plane,
124 enum dma_data_direction dir)
125{
bf4c54a4
JK
126 if (is_dma_coherent(dev))
127 return;
128
07e82f1a
CK
129 if (plane->dmabuf)
130 dma_sync_sg_for_cpu(dev, plane->sgt->sgl,
131 plane->sgt->orig_nents, dir);
132 else
133 exynos_iommu_sync_for_cpu(dev, plane->dma_addr,
134 plane->bytes_used, dir);
135}
136EXPORT_SYMBOL(m2m1shot_sync_for_cpu);