forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/rknpu/rknpu_mem.c
....@@ -15,7 +15,8 @@
1515 #include "rknpu_ioctl.h"
1616 #include "rknpu_mem.h"
1717
18
-int rknpu_mem_create_ioctl(struct rknpu_device *rknpu_dev, unsigned long data)
18
+int rknpu_mem_create_ioctl(struct rknpu_device *rknpu_dev, unsigned long data,
19
+ struct file *file)
1920 {
2021 struct rknpu_mem_create args;
2122 int ret = -EINVAL;
....@@ -27,6 +28,7 @@
2728 struct page **pages;
2829 struct page *page;
2930 struct rknpu_mem_object *rknpu_obj = NULL;
31
+ struct rknpu_session *session = NULL;
3032 int i, fd;
3133 unsigned int length, page_count;
3234
....@@ -65,6 +67,8 @@
6567 O_CLOEXEC | O_RDWR, 0x0,
6668 dev_name(rknpu_dev->dev));
6769 if (IS_ERR(dmabuf)) {
70
+ LOG_ERROR("dmabuf alloc failed, args.size = %llu\n",
71
+ args.size);
6872 ret = PTR_ERR(dmabuf);
6973 goto err_free_obj;
7074 }
....@@ -74,6 +78,7 @@
7478
7579 fd = dma_buf_fd(dmabuf, O_CLOEXEC | O_RDWR);
7680 if (fd < 0) {
81
+ LOG_ERROR("dmabuf fd get failed\n");
7782 ret = -EFAULT;
7883 goto err_free_dma_buf;
7984 }
....@@ -81,12 +86,14 @@
8186
8287 attachment = dma_buf_attach(dmabuf, rknpu_dev->dev);
8388 if (IS_ERR(attachment)) {
89
+ LOG_ERROR("dma_buf_attach failed\n");
8490 ret = PTR_ERR(attachment);
8591 goto err_free_dma_buf;
8692 }
8793
8894 table = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
8995 if (IS_ERR(table)) {
96
+ LOG_ERROR("dma_buf_attach failed\n");
9097 dma_buf_detach(dmabuf, attachment);
9198 ret = PTR_ERR(table);
9299 goto err_free_dma_buf;
....@@ -103,6 +110,7 @@
103110 page_count = length >> PAGE_SHIFT;
104111 pages = kmalloc_array(page_count, sizeof(struct page), GFP_KERNEL);
105112 if (!pages) {
113
+ LOG_ERROR("alloc pages failed\n");
106114 ret = -ENOMEM;
107115 goto err_detach_dma_buf;
108116 }
....@@ -112,6 +120,7 @@
112120
113121 rknpu_obj->kv_addr = vmap(pages, page_count, VM_MAP, PAGE_KERNEL);
114122 if (!rknpu_obj->kv_addr) {
123
+ LOG_ERROR("vmap pages addr failed\n");
115124 ret = -ENOMEM;
116125 goto err_free_pages;
117126 }
....@@ -141,6 +150,18 @@
141150 dma_buf_unmap_attachment(attachment, table, DMA_BIDIRECTIONAL);
142151 dma_buf_detach(dmabuf, attachment);
143152
153
+ spin_lock(&rknpu_dev->lock);
154
+
155
+ session = file->private_data;
156
+ if (!session) {
157
+ spin_unlock(&rknpu_dev->lock);
158
+ ret = -EFAULT;
159
+ goto err_unmap_kv_addr;
160
+ }
161
+ list_add_tail(&rknpu_obj->head, &session->list);
162
+
163
+ spin_unlock(&rknpu_dev->lock);
164
+
144165 return 0;
145166
146167 err_unmap_kv_addr:
....@@ -166,11 +187,12 @@
166187 return ret;
167188 }
168189
169
-int rknpu_mem_destroy_ioctl(struct rknpu_device *rknpu_dev, unsigned long data)
190
+int rknpu_mem_destroy_ioctl(struct rknpu_device *rknpu_dev, unsigned long data,
191
+ struct file *file)
170192 {
171
- struct rknpu_mem_object *rknpu_obj = NULL;
193
+ struct rknpu_mem_object *rknpu_obj, *entry, *q;
194
+ struct rknpu_session *session = NULL;
172195 struct rknpu_mem_destroy args;
173
- struct dma_buf *dmabuf;
174196 int ret = -EFAULT;
175197
176198 if (unlikely(copy_from_user(&args, (struct rknpu_mem_destroy *)data,
....@@ -188,21 +210,82 @@
188210 }
189211
190212 rknpu_obj = (struct rknpu_mem_object *)(uintptr_t)args.obj_addr;
191
- dmabuf = rknpu_obj->dmabuf;
192213 LOG_DEBUG(
193214 "free args.handle: %d, rknpu_obj: %#llx, rknpu_obj->dma_addr: %#llx\n",
194215 args.handle, (__u64)(uintptr_t)rknpu_obj,
195216 (__u64)rknpu_obj->dma_addr);
196217
197
- vunmap(rknpu_obj->kv_addr);
198
- rknpu_obj->kv_addr = NULL;
218
+ spin_lock(&rknpu_dev->lock);
219
+ session = file->private_data;
220
+ if (!session) {
221
+ spin_unlock(&rknpu_dev->lock);
222
+ ret = -EFAULT;
223
+ return ret;
224
+ }
225
+ list_for_each_entry_safe(entry, q, &session->list, head) {
226
+ if (entry == rknpu_obj) {
227
+ list_del(&entry->head);
228
+ break;
229
+ }
230
+ }
231
+ spin_unlock(&rknpu_dev->lock);
199232
200
- if (!rknpu_obj->owner)
201
- dma_buf_put(dmabuf);
233
+ if (rknpu_obj == entry) {
234
+ vunmap(rknpu_obj->kv_addr);
235
+ rknpu_obj->kv_addr = NULL;
202236
203
- kfree(rknpu_obj);
237
+ if (!rknpu_obj->owner)
238
+ dma_buf_put(rknpu_obj->dmabuf);
239
+
240
+ kfree(rknpu_obj);
241
+ }
204242
205243 return 0;
244
+}
245
+
246
+/*
247
+ * begin cpu access => for_cpu = true
248
+ * end cpu access => for_cpu = false
249
+ */
250
+static void __maybe_unused rknpu_dma_buf_sync(
251
+ struct rknpu_device *rknpu_dev, struct rknpu_mem_object *rknpu_obj,
252
+ u32 offset, u32 length, enum dma_data_direction dir, bool for_cpu)
253
+{
254
+ struct device *dev = rknpu_dev->dev;
255
+ struct sg_table *sgt = rknpu_obj->sgt;
256
+ struct scatterlist *sg = sgt->sgl;
257
+ dma_addr_t sg_dma_addr = sg_dma_address(sg);
258
+ unsigned int len = 0;
259
+ int i;
260
+
261
+ for_each_sgtable_sg(sgt, sg, i) {
262
+ unsigned int sg_offset, sg_left, size = 0;
263
+
264
+ len += sg->length;
265
+ if (len <= offset) {
266
+ sg_dma_addr += sg->length;
267
+ continue;
268
+ }
269
+
270
+ sg_left = len - offset;
271
+ sg_offset = sg->length - sg_left;
272
+
273
+ size = (length < sg_left) ? length : sg_left;
274
+
275
+ if (for_cpu)
276
+ dma_sync_single_range_for_cpu(dev, sg_dma_addr,
277
+ sg_offset, size, dir);
278
+ else
279
+ dma_sync_single_range_for_device(dev, sg_dma_addr,
280
+ sg_offset, size, dir);
281
+
282
+ offset += size;
283
+ length -= size;
284
+ sg_dma_addr += sg->length;
285
+
286
+ if (length == 0)
287
+ break;
288
+ }
206289 }
207290
208291 int rknpu_mem_sync_ioctl(struct rknpu_device *rknpu_dev, unsigned long data)
....@@ -229,6 +312,16 @@
229312 rknpu_obj = (struct rknpu_mem_object *)(uintptr_t)args.obj_addr;
230313 dmabuf = rknpu_obj->dmabuf;
231314
315
+#ifndef CONFIG_DMABUF_PARTIAL
316
+ if (args.flags & RKNPU_MEM_SYNC_TO_DEVICE) {
317
+ rknpu_dma_buf_sync(rknpu_dev, rknpu_obj, args.offset, args.size,
318
+ DMA_TO_DEVICE, false);
319
+ }
320
+ if (args.flags & RKNPU_MEM_SYNC_FROM_DEVICE) {
321
+ rknpu_dma_buf_sync(rknpu_dev, rknpu_obj, args.offset, args.size,
322
+ DMA_FROM_DEVICE, true);
323
+ }
324
+#else
232325 if (args.flags & RKNPU_MEM_SYNC_TO_DEVICE) {
233326 dmabuf->ops->end_cpu_access_partial(dmabuf, DMA_TO_DEVICE,
234327 args.offset, args.size);
....@@ -237,6 +330,7 @@
237330 dmabuf->ops->begin_cpu_access_partial(dmabuf, DMA_FROM_DEVICE,
238331 args.offset, args.size);
239332 }
333
+#endif
240334
241335 return 0;
242336 }