summaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorSudhir Vyas <svyas@nvidia.com>2017-11-09 08:55:43 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-11-14 12:53:43 -0500
commitcc210201488de431c0602603f0b9a5a24925be81 (patch)
tree0746da9aba6ad7f388cc3cf6c0416fa2c9b26593 /drivers/media
parent0979f851071c9ac1420d12102bd63ff8f712ffb5 (diff)
media: tegra: camera: refactor pin reloc APIs
Refactor pin and reloc API functions. Also rebase vi capture driver to capture common. Jira CRTC-1472 Change-Id: I4f6eeba8e0637ea864a8b8c3ad1220b2770e9ad1 Signed-off-by: Sudhir Vyas <svyas@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1595206 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/tegra/camera/capture_common.c51
-rw-r--r--drivers/media/platform/tegra/camera/isp/capture_isp.c118
-rw-r--r--drivers/media/platform/tegra/camera/vi/capture.c241
3 files changed, 111 insertions, 299 deletions
diff --git a/drivers/media/platform/tegra/camera/capture_common.c b/drivers/media/platform/tegra/camera/capture_common.c
index a2a4e8428..a2fc848bb 100644
--- a/drivers/media/platform/tegra/camera/capture_common.c
+++ b/drivers/media/platform/tegra/camera/capture_common.c
@@ -13,7 +13,7 @@
13#include <linux/dma-buf.h> 13#include <linux/dma-buf.h>
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/nvhost.h> 15#include <linux/nvhost.h>
16#include <linux/scatterlist.h> 16#include <linux/slab.h>
17#include <media/capture_common.h> 17#include <media/capture_common.h>
18#include <media/mc_common.h> 18#include <media/mc_common.h>
19 19
@@ -81,16 +81,51 @@ void capture_common_unpin_memory(struct capture_common_buf *unpin_data)
81 81
82int capture_common_request_pin_and_reloc(struct capture_common_pin_req *req) 82int capture_common_request_pin_and_reloc(struct capture_common_pin_req *req)
83{ 83{
84 uint32_t num_relocs = req->relocs->num_relocs; 84 uint32_t *reloc_relatives;
85 void *reloc_page_addr = NULL; 85 void *reloc_page_addr = NULL;
86 int last_page = -1; 86 int last_page = -1;
87 int i; 87 int i;
88 int err = 0; 88 int err = 0;
89 89
90 dev_dbg(req->dev, "%s: relocating %u addresses", __func__, num_relocs); 90 if (!req) {
91 pr_err("%s: NULL pin request", __func__);
92 return -EINVAL;
93 }
94
95 if (req->unpins) {
96 dev_err(req->dev, "%s: request unpins already exist", __func__);
97 return -EEXIST;
98 }
91 99
92 for (i = 0; i < num_relocs; i++) { 100 req->unpins = devm_kzalloc(req->dev,
93 uint32_t reloc_relative = req->relocs->reloc_relatives[i]; 101 sizeof(struct capture_common_unpins) +
102 (sizeof(struct capture_common_buf) * req->num_relocs),
103 GFP_KERNEL);
104 if (req->unpins == NULL) {
105 dev_err(req->dev, "failed to allocate request unpins\n");
106 return -ENOMEM;
107 }
108
109 reloc_relatives = kcalloc(req->num_relocs, sizeof(uint32_t),
110 GFP_KERNEL);
111 if (reloc_relatives == NULL) {
112 dev_err(req->dev, "failed to allocate request reloc array\n");
113 err = -ENOMEM;
114 goto reloc_fail;
115 }
116
117 err = copy_from_user(reloc_relatives, req->reloc_user,
118 req->num_relocs * sizeof(uint32_t)) ? -EFAULT : 0;
119 if (err < 0) {
120 dev_err(req->dev, "failed to copy request user relocs\n");
121 goto cp_fail;
122 }
123
124 dev_dbg(req->dev, "%s: relocating %u addresses", __func__,
125 req->num_relocs);
126
127 for (i = 0; i < req->num_relocs; i++) {
128 uint32_t reloc_relative = reloc_relatives[i];
94 uint32_t reloc_offset = req->request_offset + reloc_relative; 129 uint32_t reloc_offset = req->request_offset + reloc_relative;
95 130
96 uint64_t surface_raw; 131 uint64_t surface_raw;
@@ -181,6 +216,7 @@ int capture_common_request_pin_and_reloc(struct capture_common_pin_req *req)
181 req->request_size, DMA_TO_DEVICE); 216 req->request_size, DMA_TO_DEVICE);
182 } 217 }
183 218
219 kfree(reloc_relatives);
184 return 0; 220 return 0;
185 221
186fail: 222fail:
@@ -191,5 +227,10 @@ fail:
191 for (i = 0; i < req->unpins->num_unpins; i++) 227 for (i = 0; i < req->unpins->num_unpins; i++)
192 capture_common_unpin_memory(&req->unpins->data[i]); 228 capture_common_unpin_memory(&req->unpins->data[i]);
193 229
230cp_fail:
231 kfree(reloc_relatives);
232
233reloc_fail:
234 devm_kfree(req->dev, req->unpins);
194 return err; 235 return err;
195} 236}
diff --git a/drivers/media/platform/tegra/camera/isp/capture_isp.c b/drivers/media/platform/tegra/camera/isp/capture_isp.c
index 4da20845a..60a1f08e1 100644
--- a/drivers/media/platform/tegra/camera/isp/capture_isp.c
+++ b/drivers/media/platform/tegra/camera/isp/capture_isp.c
@@ -716,14 +716,12 @@ static void isp_capture_request_unpin(struct tegra_isp_channel *chan,
716 716
717 mutex_lock(&capture->capture_desc_ctx.unpins_list_lock); 717 mutex_lock(&capture->capture_desc_ctx.unpins_list_lock);
718 unpins = capture->capture_desc_ctx.unpins_list[buffer_index]; 718 unpins = capture->capture_desc_ctx.unpins_list[buffer_index];
719 if (unpins == NULL) { 719 if (unpins != NULL) {
720 mutex_unlock(&capture->capture_desc_ctx.unpins_list_lock); 720 for (i = 0; i < unpins->num_unpins; i++)
721 return; 721 capture_common_unpin_memory(&unpins->data[i]);
722 devm_kfree(chan->isp_dev, unpins);
723 capture->capture_desc_ctx.unpins_list[buffer_index] = NULL;
722 } 724 }
723 for (i = 0; i < unpins->num_unpins; i++)
724 capture_common_unpin_memory(&unpins->data[i]);
725 devm_kfree(chan->isp_dev, unpins);
726 capture->capture_desc_ctx.unpins_list[buffer_index] = NULL;
727 mutex_unlock(&capture->capture_desc_ctx.unpins_list_lock); 725 mutex_unlock(&capture->capture_desc_ctx.unpins_list_lock);
728} 726}
729 727
@@ -736,14 +734,12 @@ static void isp_capture_program_request_unpin(struct tegra_isp_channel *chan,
736 734
737 mutex_lock(&capture->program_desc_ctx.unpins_list_lock); 735 mutex_lock(&capture->program_desc_ctx.unpins_list_lock);
738 unpins = capture->program_desc_ctx.unpins_list[buffer_index]; 736 unpins = capture->program_desc_ctx.unpins_list[buffer_index];
739 if (unpins == NULL) { 737 if (unpins != NULL) {
740 mutex_unlock(&capture->program_desc_ctx.unpins_list_lock); 738 for (i = 0; i < unpins->num_unpins; i++)
741 return; 739 capture_common_unpin_memory(&unpins->data[i]);
740 devm_kfree(chan->isp_dev, unpins);
741 capture->program_desc_ctx.unpins_list[buffer_index] = NULL;
742 } 742 }
743 for (i = 0; i < unpins->num_unpins; i++)
744 capture_common_unpin_memory(&unpins->data[i]);
745 devm_kfree(chan->isp_dev, unpins);
746 capture->program_desc_ctx.unpins_list[buffer_index] = NULL;
747 mutex_unlock(&capture->program_desc_ctx.unpins_list_lock); 743 mutex_unlock(&capture->program_desc_ctx.unpins_list_lock);
748} 744}
749 745
@@ -753,10 +749,8 @@ int isp_capture_program_request(struct tegra_isp_channel *chan,
753 struct isp_capture *capture = chan->capture_data; 749 struct isp_capture *capture = chan->capture_data;
754 struct CAPTURE_MSG capture_msg; 750 struct CAPTURE_MSG capture_msg;
755 int err = 0; 751 int err = 0;
756 struct capture_common_unpins *unpins; 752 struct capture_common_unpins *unpins = NULL;
757 struct capture_common_pin_req cap_common_req; 753 struct capture_common_pin_req cap_common_req;
758 struct capture_common_relocs *relocs;
759 uint32_t __user *reloc_relatives;
760 754
761 if (capture == NULL) { 755 if (capture == NULL) {
762 dev_err(chan->isp_dev, 756 dev_err(chan->isp_dev,
@@ -777,35 +771,6 @@ int isp_capture_program_request(struct tegra_isp_channel *chan,
777 req->buffer_index; 771 req->buffer_index;
778 772
779 /* memory pin and reloc */ 773 /* memory pin and reloc */
780 unpins = devm_kzalloc(chan->isp_dev,
781 sizeof(struct capture_common_unpins) +
782 (sizeof(struct capture_common_buf) *
783 req->isp_program_relocs.num_relocs),
784 GFP_KERNEL);
785 if (unpins == NULL)
786 return -ENOMEM;
787
788 relocs = devm_kzalloc(chan->isp_dev,
789 sizeof(struct capture_common_relocs) +
790 (sizeof(uint32_t) * req->isp_program_relocs.num_relocs),
791 GFP_KERNEL);
792 if (unlikely(relocs == NULL)) {
793 dev_err(chan->isp_dev, "failed to allocate relocs\n");
794 goto fail;
795 }
796
797 relocs->num_relocs = req->isp_program_relocs.num_relocs;
798
799 reloc_relatives = (uint32_t __user *)
800 (uintptr_t)req->isp_program_relocs.reloc_relatives;
801
802 err = copy_from_user(relocs->reloc_relatives, reloc_relatives,
803 relocs->num_relocs * sizeof(uint32_t)) ? -EFAULT : 0;
804 if (err < 0) {
805 dev_err(chan->isp_dev, "failed to copy program user-relocs\n");
806 goto reloc_fail;
807 }
808
809 cap_common_req.dev = chan->isp_dev; 774 cap_common_req.dev = chan->isp_dev;
810 cap_common_req.rtcpu_dev = capture->rtcpu_dev; 775 cap_common_req.rtcpu_dev = capture->rtcpu_dev;
811 cap_common_req.unpins = unpins; 776 cap_common_req.unpins = unpins;
@@ -814,10 +779,16 @@ int isp_capture_program_request(struct tegra_isp_channel *chan,
814 cap_common_req.request_size = capture->program_desc_ctx.request_size; 779 cap_common_req.request_size = capture->program_desc_ctx.request_size;
815 cap_common_req.request_offset = req->buffer_index * 780 cap_common_req.request_offset = req->buffer_index *
816 capture->program_desc_ctx.request_size; 781 capture->program_desc_ctx.request_size;
817 cap_common_req.relocs = relocs;
818 cap_common_req.requests_mem = capture->program_desc_ctx.desc_mem; 782 cap_common_req.requests_mem = capture->program_desc_ctx.desc_mem;
783 cap_common_req.num_relocs = req->isp_program_relocs.num_relocs;
784 cap_common_req.reloc_user = (uint32_t __user *)
785 (uintptr_t)req->isp_program_relocs.reloc_relatives;
819 786
820 capture_common_request_pin_and_reloc(&cap_common_req); 787 err = capture_common_request_pin_and_reloc(&cap_common_req);
788 if (err < 0) {
789 dev_err(chan->isp_dev, "request pin and reloc failed\n");
790 goto fail;
791 }
821 792
822 /* add pinned memory ctx to unpins_list */ 793 /* add pinned memory ctx to unpins_list */
823 mutex_lock(&capture->program_desc_ctx.unpins_list_lock); 794 mutex_lock(&capture->program_desc_ctx.unpins_list_lock);
@@ -832,13 +803,11 @@ int isp_capture_program_request(struct tegra_isp_channel *chan,
832 sizeof(capture_msg)); 803 sizeof(capture_msg));
833 if (err < 0) { 804 if (err < 0) {
834 dev_err(chan->isp_dev, "IVC program submit failed\n"); 805 dev_err(chan->isp_dev, "IVC program submit failed\n");
835 goto reloc_fail; 806 goto fail;
836 } 807 }
837 808
838 return 0; 809 return 0;
839 810
840reloc_fail:
841 devm_kfree(chan->isp_dev, relocs);
842fail: 811fail:
843 isp_capture_program_request_unpin(chan, req->buffer_index); 812 isp_capture_program_request_unpin(chan, req->buffer_index);
844 return err; 813 return err;
@@ -880,10 +849,8 @@ int isp_capture_request(struct tegra_isp_channel *chan,
880{ 849{
881 struct isp_capture *capture = chan->capture_data; 850 struct isp_capture *capture = chan->capture_data;
882 struct CAPTURE_MSG capture_msg; 851 struct CAPTURE_MSG capture_msg;
883 struct capture_common_unpins *unpins; 852 struct capture_common_unpins *unpins = NULL;
884 struct capture_common_pin_req cap_common_req; 853 struct capture_common_pin_req cap_common_req;
885 struct capture_common_relocs *relocs;
886 uint32_t __user *reloc_relatives;
887 int err = 0; 854 int err = 0;
888 855
889 if (capture == NULL) { 856 if (capture == NULL) {
@@ -903,35 +870,6 @@ int isp_capture_request(struct tegra_isp_channel *chan,
903 capture_msg.header.channel_id = capture->channel_id; 870 capture_msg.header.channel_id = capture->channel_id;
904 capture_msg.capture_isp_request_req.buffer_index = req->buffer_index; 871 capture_msg.capture_isp_request_req.buffer_index = req->buffer_index;
905 872
906 unpins = devm_kzalloc(chan->isp_dev,
907 sizeof(struct capture_common_unpins) +
908 (sizeof(struct capture_common_buf) *
909 req->isp_relocs.num_relocs),
910 GFP_KERNEL);
911 if (unpins == NULL)
912 return -ENOMEM;
913
914 relocs = devm_kzalloc(chan->isp_dev,
915 sizeof(struct capture_common_relocs) +
916 (sizeof(uint32_t) * req->isp_relocs.num_relocs),
917 GFP_KERNEL);
918 if (unlikely(relocs == NULL)) {
919 dev_err(chan->isp_dev, "failed to allocate relocs\n");
920 goto fail;
921 }
922
923 relocs->num_relocs = req->isp_relocs.num_relocs;
924
925 reloc_relatives = (uint32_t __user *)
926 (uintptr_t)req->isp_relocs.reloc_relatives;
927
928 err = copy_from_user(relocs->reloc_relatives, reloc_relatives,
929 relocs->num_relocs * sizeof(uint32_t)) ? -EFAULT : 0;
930 if (err < 0) {
931 dev_err(chan->isp_dev, "failed to copy request user relocs\n");
932 goto reloc_fail;
933 }
934
935 /* pin and reloc */ 873 /* pin and reloc */
936 cap_common_req.dev = chan->isp_dev; 874 cap_common_req.dev = chan->isp_dev;
937 cap_common_req.rtcpu_dev = capture->rtcpu_dev; 875 cap_common_req.rtcpu_dev = capture->rtcpu_dev;
@@ -941,10 +879,16 @@ int isp_capture_request(struct tegra_isp_channel *chan,
941 cap_common_req.request_size = capture->capture_desc_ctx.request_size; 879 cap_common_req.request_size = capture->capture_desc_ctx.request_size;
942 cap_common_req.request_offset = req->buffer_index * 880 cap_common_req.request_offset = req->buffer_index *
943 capture->capture_desc_ctx.request_size; 881 capture->capture_desc_ctx.request_size;
944 cap_common_req.relocs = relocs;
945 cap_common_req.requests_mem = capture->capture_desc_ctx.desc_mem; 882 cap_common_req.requests_mem = capture->capture_desc_ctx.desc_mem;
883 cap_common_req.num_relocs = req->isp_relocs.num_relocs;
884 cap_common_req.reloc_user = (uint32_t __user *)
885 (uintptr_t)req->isp_relocs.reloc_relatives;
946 886
947 capture_common_request_pin_and_reloc(&cap_common_req); 887 err = capture_common_request_pin_and_reloc(&cap_common_req);
888 if (err < 0) {
889 dev_err(chan->isp_dev, "request pin and reloc failed\n");
890 goto fail;
891 }
948 892
949 /* add pinned memory ctx to unpins_list */ 893 /* add pinned memory ctx to unpins_list */
950 mutex_lock(&capture->capture_desc_ctx.unpins_list_lock); 894 mutex_lock(&capture->capture_desc_ctx.unpins_list_lock);
@@ -959,13 +903,11 @@ int isp_capture_request(struct tegra_isp_channel *chan,
959 sizeof(capture_msg)); 903 sizeof(capture_msg));
960 if (err < 0) { 904 if (err < 0) {
961 dev_err(chan->isp_dev, "IVC capture submit failed\n"); 905 dev_err(chan->isp_dev, "IVC capture submit failed\n");
962 goto reloc_fail; 906 goto fail;
963 } 907 }
964 908
965 return 0; 909 return 0;
966 910
967reloc_fail:
968 devm_kfree(chan->isp_dev, relocs);
969fail: 911fail:
970 isp_capture_request_unpin(chan, req->buffer_index); 912 isp_capture_request_unpin(chan, req->buffer_index);
971 return err; 913 return err;
diff --git a/drivers/media/platform/tegra/camera/vi/capture.c b/drivers/media/platform/tegra/camera/vi/capture.c
index c1d24d101..9cf1de17f 100644
--- a/drivers/media/platform/tegra/camera/vi/capture.c
+++ b/drivers/media/platform/tegra/camera/vi/capture.c
@@ -11,16 +11,14 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14#include <linux/uaccess.h> 14
15#include <linux/completion.h> 15#include <linux/completion.h>
16#include <linux/dma-buf.h>
17#include <linux/dma-mapping.h>
18#include <linux/nvhost.h> 16#include <linux/nvhost.h>
19#include <linux/of_platform.h> 17#include <linux/of_platform.h>
20#include <linux/printk.h> 18#include <linux/printk.h>
21#include <linux/scatterlist.h>
22#include <linux/tegra-capture-ivc.h> 19#include <linux/tegra-capture-ivc.h>
23#include <media/capture.h> 20#include <media/capture.h>
21#include <media/capture_common.h>
24#include <media/capture_vi_channel.h> 22#include <media/capture_vi_channel.h>
25 23
26#include "soc/tegra/camrtc-capture.h" 24#include "soc/tegra/camrtc-capture.h"
@@ -40,23 +38,11 @@
40#define CAPTURE_CHANNEL_INVALID_ID 0xFFFF 38#define CAPTURE_CHANNEL_INVALID_ID 0xFFFF
41#define CAPTURE_CHANNEL_INVALID_MASK 0llu 39#define CAPTURE_CHANNEL_INVALID_MASK 0llu
42 40
43struct vi_capture_buf {
44 struct dma_buf *buf;
45 struct dma_buf_attachment *attach;
46 struct sg_table *sgt;
47 dma_addr_t iova;
48};
49
50struct vi_capture_unpins {
51 uint32_t num_unpins;
52 struct vi_capture_buf data[];
53};
54
55struct vi_capture { 41struct vi_capture {
56 uint16_t channel_id; 42 uint16_t channel_id;
57 struct device *rtcpu_dev; 43 struct device *rtcpu_dev;
58 struct tegra_vi_channel *vi_channel; 44 struct tegra_vi_channel *vi_channel;
59 struct vi_capture_buf requests; 45 struct capture_common_buf requests;
60 size_t request_buf_size; 46 size_t request_buf_size;
61 uint32_t queue_depth; 47 uint32_t queue_depth;
62 uint32_t request_size; 48 uint32_t request_size;
@@ -71,7 +57,7 @@ struct vi_capture {
71 struct CAPTURE_CONTROL_MSG control_resp_msg; 57 struct CAPTURE_CONTROL_MSG control_resp_msg;
72 58
73 struct mutex unpins_list_lock; 59 struct mutex unpins_list_lock;
74 struct vi_capture_unpins **unpins_list; 60 struct capture_common_unpins **unpins_list;
75}; 61};
76 62
77static void vi_capture_ivc_control_callback(const void *ivc_resp, 63static void vi_capture_ivc_control_callback(const void *ivc_resp,
@@ -258,67 +244,6 @@ fail:
258 return err; 244 return err;
259} 245}
260 246
261static int pin_memory(struct device *dev,
262 uint32_t mem, struct vi_capture_buf *unpin_data);
263static void unpin_memory(struct vi_capture_buf *unpin_data);
264
265static int pin_memory(struct device *dev,
266 uint32_t mem, struct vi_capture_buf *unpin_data)
267{
268 struct dma_buf *buf;
269 struct dma_buf_attachment *attach;
270 struct sg_table *sgt;
271 int err = 0;
272
273 buf = dma_buf_get(mem);
274 if (IS_ERR(buf)) {
275 err = PTR_ERR(buf);
276 goto fail;
277 }
278
279 attach = dma_buf_attach(buf, dev);
280 if (IS_ERR(attach)) {
281 err = PTR_ERR(attach);
282 goto fail;
283 }
284
285 sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
286 if (IS_ERR(sgt)) {
287 err = PTR_ERR(sgt);
288 goto fail;
289 }
290
291 if (sg_dma_address(sgt->sgl) == 0)
292 sg_dma_address(sgt->sgl) = sg_phys(sgt->sgl);
293
294 unpin_data->iova = sg_dma_address(sgt->sgl);
295 unpin_data->buf = buf;
296 unpin_data->attach = attach;
297 unpin_data->sgt = sgt;
298
299 return 0;
300
301fail:
302 unpin_memory(unpin_data);
303 return err;
304}
305
306static void unpin_memory(struct vi_capture_buf *unpin_data)
307{
308 if (unpin_data->sgt != NULL)
309 dma_buf_unmap_attachment(unpin_data->attach, unpin_data->sgt,
310 DMA_BIDIRECTIONAL);
311 if (unpin_data->attach != NULL)
312 dma_buf_detach(unpin_data->buf, unpin_data->attach);
313 if (unpin_data->buf != NULL)
314 dma_buf_put(unpin_data->buf);
315
316 unpin_data->sgt = NULL;
317 unpin_data->attach = NULL;
318 unpin_data->buf = NULL;
319 unpin_data->iova = 0;
320}
321
322static int vi_capture_setup_syncpts(struct tegra_vi_channel *chan, 247static int vi_capture_setup_syncpts(struct tegra_vi_channel *chan,
323 uint32_t flags); 248 uint32_t flags);
324static void vi_capture_release_syncpts(struct tegra_vi_channel *chan); 249static void vi_capture_release_syncpts(struct tegra_vi_channel *chan);
@@ -433,7 +358,8 @@ int vi_capture_setup(struct tegra_vi_channel *chan,
433 /* pin the capture descriptor ring buffer */ 358 /* pin the capture descriptor ring buffer */
434 dev_dbg(chan->dev, "%s: descr buffer handle %u\n", 359 dev_dbg(chan->dev, "%s: descr buffer handle %u\n",
435 __func__, setup->mem); 360 __func__, setup->mem);
436 err = pin_memory(capture->rtcpu_dev, setup->mem, &capture->requests); 361 err = capture_common_pin_memory(capture->rtcpu_dev,
362 setup->mem, &capture->requests);
437 if (err < 0) { 363 if (err < 0) {
438 dev_err(chan->dev, "%s: memory setup failed\n", __func__); 364 dev_err(chan->dev, "%s: memory setup failed\n", __func__);
439 return -EFAULT; 365 return -EFAULT;
@@ -444,7 +370,8 @@ int vi_capture_setup(struct tegra_vi_channel *chan,
444 370
445 /* allocate for unpin list based on queue depth */ 371 /* allocate for unpin list based on queue depth */
446 capture->unpins_list = devm_kzalloc(chan->dev, 372 capture->unpins_list = devm_kzalloc(chan->dev,
447 sizeof(struct vi_capture_unpins *) * capture->queue_depth, 373 sizeof(struct capture_common_unpins *) *
374 capture->queue_depth,
448 GFP_KERNEL); 375 GFP_KERNEL);
449 if (unlikely(capture->unpins_list == NULL)) { 376 if (unlikely(capture->unpins_list == NULL)) {
450 dev_err(chan->dev, "failed to allocate unpins array\n"); 377 dev_err(chan->dev, "failed to allocate unpins array\n");
@@ -521,7 +448,7 @@ control_cb_fail:
521syncpt_fail: 448syncpt_fail:
522 devm_kfree(chan->dev, capture->unpins_list); 449 devm_kfree(chan->dev, capture->unpins_list);
523unpins_list_fail: 450unpins_list_fail:
524 unpin_memory(&capture->requests); 451 capture_common_unpin_memory(&capture->requests);
525 return err; 452 return err;
526} 453}
527 454
@@ -675,7 +602,7 @@ int vi_capture_release(struct tegra_vi_channel *chan,
675 vi_capture_request_unpin(chan, i); 602 vi_capture_request_unpin(chan, i);
676 603
677 vi_capture_release_syncpts(chan); 604 vi_capture_release_syncpts(chan);
678 unpin_memory(&capture->requests); 605 capture_common_unpin_memory(&capture->requests);
679 606
680 capture->channel_id = CAPTURE_CHANNEL_INVALID_ID; 607 capture->channel_id = CAPTURE_CHANNEL_INVALID_ID;
681 608
@@ -825,136 +752,18 @@ struct surface_t {
825 uint32_t offset_hi; 752 uint32_t offset_hi;
826}; 753};
827 754
828static int vi_capture_request_pin_and_reloc(struct tegra_vi_channel *chan,
829 struct vi_capture_req *req)
830{
831 struct vi_capture *capture = chan->capture_data;
832 uint32_t num_relocs = req->num_relocs;
833 uint32_t __user *reloc_relatives =
834 (uint32_t __user *)(uintptr_t)req->reloc_relatives;
835 uint32_t local_reloc_relatives[VI_NUM_ATOMP_SURFACES];
836 struct vi_capture_unpins *unpins;
837 uint32_t request_offset = req->buffer_index * capture->request_size;
838 void *reloc_page_addr = NULL;
839 uint32_t prev_mem = 0;
840 int last_page = -1;
841 dma_addr_t surface_phys_addr = 0;
842 int i = 0;
843 int err = 0;
844
845 err = copy_from_user(local_reloc_relatives, reloc_relatives,
846 num_relocs * sizeof(uint32_t)) ? -EFAULT : 0;
847 if (err < 0)
848 return err;
849
850 unpins = devm_kzalloc(chan->dev,
851 sizeof(struct vi_capture_unpins) +
852 sizeof(struct vi_capture_buf) * num_relocs,
853 GFP_KERNEL);
854 if (unpins == NULL)
855 return -ENOMEM;
856
857 dev_dbg(chan->dev, "%s: relocating %u surfaces\n",
858 __func__, num_relocs);
859 for (i = 0; i < num_relocs; i++) {
860 uint32_t reloc_offset =
861 request_offset + local_reloc_relatives[i];
862 uint64_t surface_raw;
863 struct surface_t *surface;
864 uint32_t mem;
865 uint32_t target_offset;
866 dma_addr_t target_phys_addr;
867
868 dev_dbg(chan->dev,
869 "%s: idx:%i reloc:%u reloc_offset:%u", __func__,
870 i, local_reloc_relatives[i], reloc_offset);
871
872 /* locate page of the request descr buffer relocation is on */
873 if (last_page != reloc_offset >> PAGE_SHIFT) {
874 if (reloc_page_addr != NULL)
875 dma_buf_kunmap(capture->requests.buf, last_page,
876 reloc_page_addr);
877
878 reloc_page_addr = dma_buf_kmap(capture->requests.buf,
879 reloc_offset >> PAGE_SHIFT);
880 last_page = reloc_offset >> PAGE_SHIFT;
881
882 if (unlikely(reloc_page_addr == NULL)) {
883 dev_err(chan->dev,
884 "%s: couldn't map request\n", __func__);
885 goto fail;
886 }
887 }
888
889 /* read surface offset and memory handle from request descr */
890 surface_raw = __raw_readq(
891 (void __iomem *)(reloc_page_addr +
892 (reloc_offset & ~PAGE_MASK)));
893 surface = (struct surface_t *)&surface_raw;
894 target_offset = surface->offset;
895 mem = surface->offset_hi;
896 dev_dbg(chan->dev, "%s: hmem:%u offset:%u\n", __func__,
897 mem, target_offset);
898
899 if (mem != prev_mem) {
900 err = pin_memory(chan->dev,
901 mem, &unpins->data[unpins->num_unpins]);
902 if (err < 0) {
903 goto fail;
904 }
905 unpins->num_unpins++;
906 surface_phys_addr = unpins->data[i].iova;
907 }
908
909 target_phys_addr = surface_phys_addr + target_offset;
910 dev_dbg(chan->dev, "%s: surface addr %lx at desc %lx\n",
911 __func__, (unsigned long)target_phys_addr,
912 (unsigned long)reloc_page_addr +
913 (reloc_offset & ~PAGE_MASK));
914
915 /* write relocated physical address to request descr */
916 __raw_writeq(
917 target_phys_addr,
918 (void __iomem *)(reloc_page_addr +
919 (reloc_offset & ~PAGE_MASK)));
920
921 dma_sync_single_range_for_device(capture->rtcpu_dev,
922 capture->requests.iova, request_offset,
923 capture->request_size, DMA_TO_DEVICE);
924 }
925
926 /* assign the unpins list to the capture to be unpinned and */
927 /* freed at capture completion (vi_capture_request_unpin) */
928 mutex_lock(&capture->unpins_list_lock);
929 capture->unpins_list[req->buffer_index] = unpins;
930 mutex_unlock(&capture->unpins_list_lock);
931
932 return 0;
933
934fail:
935 if (reloc_page_addr != NULL)
936 dma_buf_kunmap(capture->requests.buf, last_page,
937 reloc_page_addr);
938
939 for (i = 0; i < unpins->num_unpins; i++)
940 unpin_memory(&unpins->data[i]);
941 devm_kfree(chan->dev, unpins);
942
943 return err;
944}
945
946static void vi_capture_request_unpin(struct tegra_vi_channel *chan, 755static void vi_capture_request_unpin(struct tegra_vi_channel *chan,
947 uint32_t buffer_index) 756 uint32_t buffer_index)
948{ 757{
949 struct vi_capture *capture = chan->capture_data; 758 struct vi_capture *capture = chan->capture_data;
950 struct vi_capture_unpins *unpins; 759 struct capture_common_unpins *unpins;
951 int i = 0; 760 int i = 0;
952 761
953 mutex_lock(&capture->unpins_list_lock); 762 mutex_lock(&capture->unpins_list_lock);
954 unpins = capture->unpins_list[buffer_index]; 763 unpins = capture->unpins_list[buffer_index];
955 if (unpins != NULL) { 764 if (unpins != NULL) {
956 for (i = 0; i < unpins->num_unpins; i++) 765 for (i = 0; i < unpins->num_unpins; i++)
957 unpin_memory(&unpins->data[i]); 766 capture_common_unpin_memory(&unpins->data[i]);
958 capture->unpins_list[buffer_index] = NULL; 767 capture->unpins_list[buffer_index] = NULL;
959 devm_kfree(chan->dev, unpins); 768 devm_kfree(chan->dev, unpins);
960 } 769 }
@@ -966,6 +775,8 @@ int vi_capture_request(struct tegra_vi_channel *chan,
966{ 775{
967 struct vi_capture *capture = chan->capture_data; 776 struct vi_capture *capture = chan->capture_data;
968 struct CAPTURE_MSG capture_desc; 777 struct CAPTURE_MSG capture_desc;
778 struct capture_common_unpins *unpins = NULL;
779 struct capture_common_pin_req cap_common_req = {0};
969 int err = 0; 780 int err = 0;
970 781
971 if (capture == NULL) { 782 if (capture == NULL) {
@@ -985,13 +796,31 @@ int vi_capture_request(struct tegra_vi_channel *chan,
985 capture_desc.header.channel_id = capture->channel_id; 796 capture_desc.header.channel_id = capture->channel_id;
986 capture_desc.capture_request_req.buffer_index = req->buffer_index; 797 capture_desc.capture_request_req.buffer_index = req->buffer_index;
987 798
988 /* perform surface pinning and relocation */ 799 /* pin and reloc */
989 err = vi_capture_request_pin_and_reloc(chan, req); 800 cap_common_req.dev = chan->dev;
801 cap_common_req.rtcpu_dev = capture->rtcpu_dev;
802 cap_common_req.unpins = unpins;
803 cap_common_req.requests = &capture->requests;
804 cap_common_req.requests_dev = NULL;
805 cap_common_req.request_size = capture->request_size;
806 cap_common_req.request_offset = req->buffer_index *
807 capture->request_size;
808 cap_common_req.num_relocs = req->num_relocs;
809 cap_common_req.reloc_user = (uint32_t __user *)
810 (uintptr_t)req->reloc_relatives;
811
812 err = capture_common_request_pin_and_reloc(&cap_common_req);
990 if (err < 0) { 813 if (err < 0) {
991 dev_err(chan->dev, "relocation failed\n"); 814 dev_err(chan->dev, "request relocation failed\n");
992 return err; 815 return err;
993 } 816 }
994 817
818 /* assign the unpins list to the capture to be unpinned and */
819 /* freed at capture completion (vi_capture_request_unpin) */
820 mutex_lock(&capture->unpins_list_lock);
821 capture->unpins_list[req->buffer_index] = unpins;
822 mutex_unlock(&capture->unpins_list_lock);
823
995 dev_dbg(chan->dev, "%s: sending chan_id %u msg_id %u buf:%u\n", 824 dev_dbg(chan->dev, "%s: sending chan_id %u msg_id %u buf:%u\n",
996 __func__, capture_desc.header.channel_id, 825 __func__, capture_desc.header.channel_id,
997 capture_desc.header.msg_id, req->buffer_index); 826 capture_desc.header.msg_id, req->buffer_index);