forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/video/rockchip/mpp/mpp_common.c
....@@ -36,14 +36,6 @@
3636 #include "mpp_common.h"
3737 #include "mpp_iommu.h"
3838
39
-#define MPP_WAIT_TIMEOUT_DELAY (2000)
40
-
41
-/* Use 'v' as magic number */
42
-#define MPP_IOC_MAGIC 'v'
43
-
44
-#define MPP_IOC_CFG_V1 _IOW(MPP_IOC_MAGIC, 1, unsigned int)
45
-#define MPP_IOC_CFG_V2 _IOW(MPP_IOC_MAGIC, 2, unsigned int)
46
-
4739 /* input parmater structure for version 1 */
4840 struct mpp_msg_v1 {
4941 __u32 cmd;
....@@ -59,12 +51,15 @@
5951 [MPP_DEVICE_VDPU2] = "VDPU2",
6052 [MPP_DEVICE_VDPU1_PP] = "VDPU1_PP",
6153 [MPP_DEVICE_VDPU2_PP] = "VDPU2_PP",
54
+ [MPP_DEVICE_AV1DEC] = "AV1DEC",
6255 [MPP_DEVICE_HEVC_DEC] = "HEVC_DEC",
6356 [MPP_DEVICE_RKVDEC] = "RKVDEC",
6457 [MPP_DEVICE_AVSPLUS_DEC] = "AVSPLUS_DEC",
58
+ [MPP_DEVICE_RKJPEGD] = "RKJPEGD",
6559 [MPP_DEVICE_RKVENC] = "RKVENC",
6660 [MPP_DEVICE_VEPU1] = "VEPU1",
6761 [MPP_DEVICE_VEPU2] = "VEPU2",
62
+ [MPP_DEVICE_VEPU2_JPEG] = "VEPU2",
6863 [MPP_DEVICE_VEPU22] = "VEPU22",
6964 [MPP_DEVICE_IEP2] = "IEP2",
7065 [MPP_DEVICE_VDPP] = "VDPP",
....@@ -86,25 +81,8 @@
8681
8782 #endif
8883
89
-static void mpp_free_task(struct kref *ref);
9084 static void mpp_attach_workqueue(struct mpp_dev *mpp,
9185 struct mpp_taskqueue *queue);
92
-
93
-/* task queue schedule */
94
-static int
95
-mpp_taskqueue_push_pending(struct mpp_taskqueue *queue,
96
- struct mpp_task *task)
97
-{
98
- if (!task->session || !task->session->mpp)
99
- return -EINVAL;
100
-
101
- kref_get(&task->ref);
102
- mutex_lock(&queue->pending_lock);
103
- list_add_tail(&task->queue_link, &queue->pending_list);
104
- mutex_unlock(&queue->pending_lock);
105
-
106
- return 0;
107
-}
10886
10987 static int
11088 mpp_taskqueue_pop_pending(struct mpp_taskqueue *queue,
....@@ -148,9 +126,7 @@
148126 return flag;
149127 }
150128
151
-static int
152
-mpp_taskqueue_pending_to_run(struct mpp_taskqueue *queue,
153
- struct mpp_task *task)
129
+int mpp_taskqueue_pending_to_run(struct mpp_taskqueue *queue, struct mpp_task *task)
154130 {
155131 unsigned long flags;
156132
....@@ -230,7 +206,104 @@
230206 return 0;
231207 }
232208
233
-static int mpp_session_clear_pending(struct mpp_session *session)
209
+static void task_msgs_reset(struct mpp_task_msgs *msgs)
210
+{
211
+ list_del_init(&msgs->list);
212
+
213
+ msgs->flags = 0;
214
+ msgs->req_cnt = 0;
215
+ msgs->set_cnt = 0;
216
+ msgs->poll_cnt = 0;
217
+}
218
+
219
+static void task_msgs_init(struct mpp_task_msgs *msgs, struct mpp_session *session)
220
+{
221
+ INIT_LIST_HEAD(&msgs->list);
222
+
223
+ msgs->session = session;
224
+ msgs->queue = NULL;
225
+ msgs->task = NULL;
226
+ msgs->mpp = NULL;
227
+
228
+ msgs->ext_fd = -1;
229
+
230
+ task_msgs_reset(msgs);
231
+}
232
+
233
+static struct mpp_task_msgs *get_task_msgs(struct mpp_session *session)
234
+{
235
+ unsigned long flags;
236
+ struct mpp_task_msgs *msgs;
237
+
238
+ spin_lock_irqsave(&session->lock_msgs, flags);
239
+ msgs = list_first_entry_or_null(&session->list_msgs_idle,
240
+ struct mpp_task_msgs, list_session);
241
+ if (msgs) {
242
+ list_move_tail(&msgs->list_session, &session->list_msgs);
243
+ spin_unlock_irqrestore(&session->lock_msgs, flags);
244
+
245
+ return msgs;
246
+ }
247
+ spin_unlock_irqrestore(&session->lock_msgs, flags);
248
+
249
+ msgs = kzalloc(sizeof(*msgs), GFP_KERNEL);
250
+ task_msgs_init(msgs, session);
251
+ INIT_LIST_HEAD(&msgs->list_session);
252
+
253
+ spin_lock_irqsave(&session->lock_msgs, flags);
254
+ list_move_tail(&msgs->list_session, &session->list_msgs);
255
+ session->msgs_cnt++;
256
+ spin_unlock_irqrestore(&session->lock_msgs, flags);
257
+
258
+ mpp_debug_func(DEBUG_TASK_INFO, "session %d:%d msgs cnt %d\n",
259
+ session->pid, session->index, session->msgs_cnt);
260
+
261
+ return msgs;
262
+}
263
+
264
+static void put_task_msgs(struct mpp_task_msgs *msgs)
265
+{
266
+ struct mpp_session *session = msgs->session;
267
+ unsigned long flags;
268
+
269
+ if (!session) {
270
+ pr_err("invalid msgs without session\n");
271
+ return;
272
+ }
273
+
274
+ if (msgs->ext_fd >= 0) {
275
+ fdput(msgs->f);
276
+ msgs->ext_fd = -1;
277
+ }
278
+
279
+ task_msgs_reset(msgs);
280
+
281
+ spin_lock_irqsave(&session->lock_msgs, flags);
282
+ list_move_tail(&msgs->list_session, &session->list_msgs_idle);
283
+ spin_unlock_irqrestore(&session->lock_msgs, flags);
284
+}
285
+
286
+static void clear_task_msgs(struct mpp_session *session)
287
+{
288
+ struct mpp_task_msgs *msgs, *n;
289
+ LIST_HEAD(list_to_free);
290
+ unsigned long flags;
291
+
292
+ spin_lock_irqsave(&session->lock_msgs, flags);
293
+
294
+ list_for_each_entry_safe(msgs, n, &session->list_msgs, list_session)
295
+ list_move_tail(&msgs->list_session, &list_to_free);
296
+
297
+ list_for_each_entry_safe(msgs, n, &session->list_msgs_idle, list_session)
298
+ list_move_tail(&msgs->list_session, &list_to_free);
299
+
300
+ spin_unlock_irqrestore(&session->lock_msgs, flags);
301
+
302
+ list_for_each_entry_safe(msgs, n, &list_to_free, list_session)
303
+ kfree(msgs);
304
+}
305
+
306
+static void mpp_session_clear_pending(struct mpp_session *session)
234307 {
235308 struct mpp_task *task = NULL, *n;
236309
....@@ -245,8 +318,6 @@
245318 kref_put(&task->ref, mpp_free_task);
246319 }
247320 mutex_unlock(&session->pending_lock);
248
-
249
- return 0;
250321 }
251322
252323 void mpp_session_cleanup_detach(struct mpp_taskqueue *queue, struct kthread_work *work)
....@@ -268,9 +339,9 @@
268339 mutex_unlock(&queue->session_lock);
269340
270341 if (task_count) {
271
- mpp_dbg_session("session %d:%d task not finished %d\n",
272
- session->pid, session->index,
273
- atomic_read(&queue->detach_count));
342
+ mpp_dbg_session("session %d:%d not finished %d task cnt %d\n",
343
+ session->device_type, session->index,
344
+ atomic_read(&queue->detach_count), task_count);
274345
275346 mpp_session_clear_pending(session);
276347 } else {
....@@ -308,6 +379,10 @@
308379
309380 atomic_set(&session->task_count, 0);
310381 atomic_set(&session->release_request, 0);
382
+
383
+ INIT_LIST_HEAD(&session->list_msgs);
384
+ INIT_LIST_HEAD(&session->list_msgs_idle);
385
+ spin_lock_init(&session->lock_msgs);
311386
312387 mpp_dbg_session("session %p init\n", session);
313388 return session;
....@@ -352,7 +427,7 @@
352427 else
353428 pr_err("invalid NULL session deinit function\n");
354429
355
- mpp_dbg_session("session %p:%d deinit\n", session, session->index);
430
+ clear_task_msgs(session);
356431
357432 kfree(session);
358433 }
....@@ -429,7 +504,7 @@
429504 return task;
430505 }
431506
432
-static void mpp_free_task(struct kref *ref)
507
+void mpp_free_task(struct kref *ref)
433508 {
434509 struct mpp_dev *mpp;
435510 struct mpp_session *session;
....@@ -441,18 +516,14 @@
441516 }
442517 session = task->session;
443518
444
- mpp_debug_func(DEBUG_TASK_INFO,
445
- "session %d:%d task %d state 0x%lx abort_request %d\n",
446
- session->device_type, session->index, task->task_index,
447
- task->state, atomic_read(&task->abort_request));
448
- if (!session->mpp) {
449
- mpp_err("session %p, session->mpp is null.\n", session);
450
- return;
451
- }
452
- mpp = session->mpp;
519
+ mpp_debug_func(DEBUG_TASK_INFO, "task %d:%d free state 0x%lx abort %d\n",
520
+ session->index, task->task_id, task->state,
521
+ atomic_read(&task->abort_request));
453522
523
+ mpp = mpp_get_task_used_device(task, session);
454524 if (mpp->dev_ops->free_task)
455525 mpp->dev_ops->free_task(session, task);
526
+
456527 /* Decrease reference count */
457528 atomic_dec(&session->task_count);
458529 atomic_dec(&mpp->task_count);
....@@ -466,10 +537,8 @@
466537 struct mpp_task,
467538 timeout_work);
468539
469
- if (!test_bit(TASK_STATE_START, &task->state)) {
470
- mpp_err("task has not start\n");
471
- schedule_delayed_work(&task->timeout_work,
472
- msecs_to_jiffies(MPP_WORK_TIMEOUT_DELAY));
540
+ if (test_and_set_bit(TASK_STATE_HANDLE, &task->state)) {
541
+ mpp_err("task has been handled\n");
473542 return;
474543 }
475544
....@@ -479,34 +548,31 @@
479548 }
480549
481550 session = task->session;
551
+ mpp_err("task %d:%d:%d processing time out!\n", session->pid,
552
+ session->index, task->task_id);
482553
483554 if (!session->mpp) {
484555 mpp_err("session %d:%d, session mpp is null.\n", session->pid,
485556 session->index);
486557 return;
487558 }
488
- mpp = session->mpp;
489
- dev_err(mpp->dev, "session %d:%d task %d state %lx processing time out!\n",
490
- session->device_type, session->index, task->task_index, task->state);
491
- synchronize_hardirq(mpp->irq);
492
-
493
- if (test_and_set_bit(TASK_STATE_HANDLE, &task->state)) {
494
- mpp_err("task has been handled\n");
495
- return;
496
- }
497559
498560 mpp_task_dump_timing(task, ktime_us_delta(ktime_get(), task->on_create));
561
+
562
+ mpp = mpp_get_task_used_device(task, session);
499563
500564 /* disable core irq */
501565 disable_irq(mpp->irq);
502566 /* disable mmu irq */
503
- mpp_iommu_disable_irq(mpp->iommu_info);
567
+ if (mpp->iommu_info && mpp->iommu_info->got_irq)
568
+ disable_irq(mpp->iommu_info->irq);
504569
505570 /* hardware maybe dead, reset it */
506571 mpp_reset_up_read(mpp->reset_group);
507572 mpp_dev_reset(mpp);
508573 mpp_power_off(mpp);
509574
575
+ mpp_iommu_dev_deactivate(mpp->iommu_info, mpp);
510576 set_bit(TASK_STATE_TIMEOUT, &task->state);
511577 set_bit(TASK_STATE_DONE, &task->state);
512578 /* Wake up the GET thread */
....@@ -518,13 +584,14 @@
518584 /* enable core irq */
519585 enable_irq(mpp->irq);
520586 /* enable mmu irq */
521
- mpp_iommu_enable_irq(mpp->iommu_info);
587
+ if (mpp->iommu_info && mpp->iommu_info->got_irq)
588
+ enable_irq(mpp->iommu_info->irq);
522589
523590 mpp_taskqueue_trigger_work(mpp);
524591 }
525592
526593 static int mpp_process_task_default(struct mpp_session *session,
527
- struct mpp_task_msgs *msgs)
594
+ struct mpp_task_msgs *msgs)
528595 {
529596 struct mpp_task *task = NULL;
530597 struct mpp_dev *mpp = session->mpp;
....@@ -532,7 +599,7 @@
532599 ktime_t on_create;
533600
534601 if (unlikely(!mpp)) {
535
- mpp_err("pid %d clinet %d found invalid process function\n",
602
+ mpp_err("pid %d client %d found invalid process function\n",
536603 session->pid, session->device_type);
537604 return -EINVAL;
538605 }
....@@ -555,14 +622,22 @@
555622 set_bit(TASK_TIMING_CREATE, &task->state);
556623 }
557624
625
+ /* ensure current device */
626
+ mpp = mpp_get_task_used_device(task, session);
627
+
558628 kref_init(&task->ref);
559629 init_waitqueue_head(&task->wait);
560630 atomic_set(&task->abort_request, 0);
561631 task->task_index = atomic_fetch_inc(&mpp->task_index);
632
+ task->task_id = atomic_fetch_inc(&mpp->queue->task_id);
562633 INIT_DELAYED_WORK(&task->timeout_work, mpp_task_timeout_work);
563634
564635 if (mpp->auto_freq_en && mpp->hw_ops->get_freq)
565636 mpp->hw_ops->get_freq(mpp, task);
637
+
638
+ msgs->queue = mpp->queue;
639
+ msgs->task = task;
640
+ msgs->mpp = mpp;
566641
567642 /*
568643 * Push task to session should be in front of push task to queue.
....@@ -572,17 +647,7 @@
572647 */
573648 atomic_inc(&session->task_count);
574649 mpp_session_push_pending(session, task);
575
- /* push current task to queue */
576
- atomic_inc(&mpp->task_count);
577
- mpp_taskqueue_push_pending(mpp->queue, task);
578
- set_bit(TASK_STATE_PENDING, &task->state);
579
- /* trigger current queue to run task */
580
- mpp_taskqueue_trigger_work(mpp);
581
- kref_put(&task->ref, mpp_free_task);
582
- mpp_debug_func(DEBUG_TASK_INFO,
583
- "session %d:%d task %d state 0x%lx\n",
584
- session->device_type, session->index,
585
- task->task_index, task->state);
650
+
586651 return 0;
587652 }
588653
....@@ -662,10 +727,9 @@
662727 mpp_iommu_down_write(mpp->iommu_info);
663728 mpp_reset_down_write(mpp->reset_group);
664729 atomic_set(&mpp->reset_request, 0);
665
- rockchip_save_qos(mpp->dev);
730
+
666731 if (mpp->hw_ops->reset)
667732 mpp->hw_ops->reset(mpp);
668
- rockchip_restore_qos(mpp->dev);
669733
670734 /* Note: if the domain does not change, iommu attach will be return
671735 * as an empty operation. Therefore, force to close and then open,
....@@ -714,7 +778,6 @@
714778 struct mpp_task *task)
715779 {
716780 int ret;
717
- struct mpp_session *session = task->session;
718781 u32 timing_en;
719782
720783 mpp_debug_enter();
....@@ -739,33 +802,32 @@
739802 mpp_set_grf(mpp->grf_info);
740803 }
741804 /*
805
+ * Lock the reader locker of the device resource lock here,
806
+ * release at the finish operation
807
+ */
808
+ mpp_reset_down_read(mpp->reset_group);
809
+
810
+ /*
742811 * for iommu share hardware, should attach to ensure
743812 * working in current device
744813 */
745814 ret = mpp_iommu_attach(mpp->iommu_info);
746815 if (ret) {
747816 dev_err(mpp->dev, "mpp_iommu_attach failed\n");
817
+ mpp_reset_up_read(mpp->reset_group);
748818 return -ENODATA;
749819 }
750820
751821 mpp_power_on(mpp);
752
- mpp_time_record(task);
753
- mpp_debug_func(DEBUG_TASK_INFO,
754
- "%s session %d:%d task=%d state=0x%lx\n",
755
- dev_name(mpp->dev), session->device_type,
756
- session->index, task->task_index, task->state);
822
+ mpp_debug_func(DEBUG_TASK_INFO, "pid %d run %s\n",
823
+ task->session->pid, dev_name(mpp->dev));
757824
758825 if (mpp->auto_freq_en && mpp->hw_ops->set_freq)
759826 mpp->hw_ops->set_freq(mpp, task);
760
- /*
761
- * TODO: Lock the reader locker of the device resource lock here,
762
- * release at the finish operation
763
- */
764
- mpp_reset_down_read(mpp->reset_group);
765827
828
+ mpp_iommu_dev_activate(mpp->iommu_info, mpp);
766829 if (mpp->dev_ops->run)
767830 mpp->dev_ops->run(mpp, task);
768
- set_bit(TASK_STATE_START, &task->state);
769831
770832 mpp_debug_leave();
771833
....@@ -780,7 +842,7 @@
780842
781843 mpp_debug_enter();
782844
783
-get_task:
845
+again:
784846 task = mpp_taskqueue_get_pending_task(queue);
785847 if (!task)
786848 goto done;
....@@ -788,7 +850,7 @@
788850 /* if task timeout and aborted, remove it */
789851 if (atomic_read(&task->abort_request) > 0) {
790852 mpp_taskqueue_pop_pending(queue, task);
791
- goto get_task;
853
+ goto again;
792854 }
793855
794856 /* get device for current task */
....@@ -813,10 +875,15 @@
813875 */
814876 /* Push a pending task to running queue */
815877 if (task) {
878
+ struct mpp_dev *task_mpp = mpp_get_task_used_device(task, task->session);
879
+
880
+ atomic_inc(&task_mpp->task_count);
816881 mpp_taskqueue_pending_to_run(queue, task);
817882 set_bit(TASK_STATE_RUNNING, &task->state);
818
- if (mpp_task_run(mpp, task))
819
- mpp_taskqueue_pop_running(mpp->queue, task);
883
+ if (mpp_task_run(task_mpp, task))
884
+ mpp_taskqueue_pop_running(queue, task);
885
+ else
886
+ goto again;
820887 }
821888
822889 done:
....@@ -824,17 +891,11 @@
824891 }
825892
826893 static int mpp_wait_result_default(struct mpp_session *session,
827
- struct mpp_task_msgs *msgs)
894
+ struct mpp_task_msgs *msgs)
828895 {
829896 int ret;
830897 struct mpp_task *task;
831
- struct mpp_dev *mpp = session->mpp;
832
-
833
- if (unlikely(!mpp)) {
834
- mpp_err("pid %d clinet %d found invalid wait result function\n",
835
- session->pid, session->device_type);
836
- return -EINVAL;
837
- }
898
+ struct mpp_dev *mpp;
838899
839900 task = mpp_session_get_pending_task(session);
840901 if (!task) {
....@@ -842,26 +903,18 @@
842903 session->pid, session->index);
843904 return -EIO;
844905 }
906
+ mpp = mpp_get_task_used_device(task, session);
845907
846
- ret = wait_event_timeout(task->wait,
847
- test_bit(TASK_STATE_DONE, &task->state),
848
- msecs_to_jiffies(MPP_WAIT_TIMEOUT_DELAY));
849
- if (ret > 0) {
850
- if (mpp->dev_ops->result)
851
- ret = mpp->dev_ops->result(mpp, task, msgs);
852
- } else {
853
- atomic_inc(&task->abort_request);
854
- set_bit(TASK_STATE_ABORT, &task->state);
855
- mpp_err("timeout, pid %d session %d:%d count %d cur_task %d state %lx\n",
856
- session->pid, session->device_type, session->index,
857
- atomic_read(&session->task_count), task->task_index, task->state);
858
- }
908
+ ret = wait_event_interruptible(task->wait, test_bit(TASK_STATE_DONE, &task->state));
909
+ if (ret == -ERESTARTSYS)
910
+ mpp_err("wait task break by signal\n");
859911
860
- mpp_debug_func(DEBUG_TASK_INFO,
861
- "session %d:%d task %d state 0x%lx kref_read %d ret %d\n",
862
- session->device_type,
863
- session->index, task->task_index, task->state,
864
- kref_read(&task->ref), ret);
912
+ if (mpp->dev_ops->result)
913
+ ret = mpp->dev_ops->result(mpp, task, msgs);
914
+ mpp_debug_func(DEBUG_TASK_INFO, "wait done session %d:%d count %d task %d state %lx\n",
915
+ session->device_type, session->index, atomic_read(&session->task_count),
916
+ task->task_index, task->state);
917
+
865918 mpp_session_pop_pending(session, task);
866919
867920 return ret;
....@@ -896,36 +949,32 @@
896949 of_node_put(np);
897950 if (!pdev) {
898951 dev_err(dev, "failed to get mpp service from node\n");
899
- ret = -ENODEV;
900
- goto err_put_pdev;
952
+ return -ENODEV;
901953 }
902954
903
- mpp->pdev_srv = pdev;
904955 mpp->srv = platform_get_drvdata(pdev);
956
+ platform_device_put(pdev);
905957 if (!mpp->srv) {
906
- dev_err(&pdev->dev, "failed attach service\n");
907
- ret = -EINVAL;
908
- goto err_put_pdev;
958
+ dev_err(dev, "failed attach service\n");
959
+ return -EINVAL;
909960 }
910961
911962 ret = of_property_read_u32(dev->of_node,
912963 "rockchip,taskqueue-node", &taskqueue_node);
913964 if (ret) {
914965 dev_err(dev, "failed to get taskqueue-node\n");
915
- goto err_put_pdev;
966
+ return ret;
916967 } else if (taskqueue_node >= mpp->srv->taskqueue_cnt) {
917968 dev_err(dev, "taskqueue-node %d must less than %d\n",
918969 taskqueue_node, mpp->srv->taskqueue_cnt);
919
- ret = -ENODEV;
920
- goto err_put_pdev;
970
+ return -ENODEV;
921971 }
922972 /* set taskqueue according dtsi */
923973 queue = mpp->srv->task_queues[taskqueue_node];
924974 if (!queue) {
925975 dev_err(dev, "taskqueue attach to invalid node %d\n",
926976 taskqueue_node);
927
- ret = -ENODEV;
928
- goto err_put_pdev;
977
+ return -ENODEV;
929978 }
930979 mpp_attach_workqueue(mpp, queue);
931980
....@@ -936,8 +985,7 @@
936985 if (reset_group_node >= mpp->srv->reset_group_cnt) {
937986 dev_err(dev, "resetgroup-node %d must less than %d\n",
938987 reset_group_node, mpp->srv->reset_group_cnt);
939
- ret = -ENODEV;
940
- goto err_put_pdev;
988
+ return -ENODEV;
941989 } else {
942990 mpp->reset_group = mpp->srv->reset_groups[reset_group_node];
943991 if (!mpp->reset_group->queue)
....@@ -948,11 +996,6 @@
948996 }
949997
950998 return 0;
951
-
952
-err_put_pdev:
953
- platform_device_put(pdev);
954
-
955
- return ret;
956999 }
9571000
9581001 struct mpp_taskqueue *mpp_taskqueue_init(struct device *dev)
....@@ -976,10 +1019,10 @@
9761019
9771020 /* default taskqueue has max 16 task capacity */
9781021 queue->task_capacity = MPP_MAX_TASK_CAPACITY;
979
-
980
- mutex_init(&queue->ref_lock);
981
- atomic_set(&queue->runtime_cnt, 0);
1022
+ atomic_set(&queue->reset_request, 0);
9821023 atomic_set(&queue->detach_count, 0);
1024
+ atomic_set(&queue->task_id, 0);
1025
+ queue->dev_active_flags = 0;
9831026
9841027 return queue;
9851028 }
....@@ -987,12 +1030,51 @@
9871030 static void mpp_attach_workqueue(struct mpp_dev *mpp,
9881031 struct mpp_taskqueue *queue)
9891032 {
990
- mpp->queue = queue;
1033
+ s32 core_id;
1034
+
9911035 INIT_LIST_HEAD(&mpp->queue_link);
1036
+
9921037 mutex_lock(&queue->dev_lock);
1038
+
1039
+ if (mpp->core_id >= 0)
1040
+ core_id = mpp->core_id;
1041
+ else
1042
+ core_id = queue->core_count;
1043
+
1044
+ if (core_id < 0 || core_id >= MPP_MAX_CORE_NUM) {
1045
+ dev_err(mpp->dev, "invalid core id %d\n", core_id);
1046
+ goto done;
1047
+ }
1048
+
1049
+ /*
1050
+ * multi devices with no multicores share one queue,
1051
+ * the core_id is default value 0.
1052
+ */
1053
+ if (queue->cores[core_id]) {
1054
+ if (queue->cores[core_id] == mpp)
1055
+ goto done;
1056
+
1057
+ core_id = queue->core_count;
1058
+ }
1059
+
1060
+ queue->cores[core_id] = mpp;
1061
+ queue->core_count++;
1062
+
1063
+ set_bit(core_id, &queue->core_idle);
9931064 list_add_tail(&mpp->queue_link, &queue->dev_list);
1065
+ if (queue->core_id_max < (u32)core_id)
1066
+ queue->core_id_max = (u32)core_id;
1067
+
1068
+ mpp->core_id = core_id;
1069
+ mpp->queue = queue;
1070
+
1071
+ mpp_dbg_core("%s attach queue as core %d\n",
1072
+ dev_name(mpp->dev), mpp->core_id);
1073
+
9941074 if (queue->task_capacity > mpp->task_capacity)
9951075 queue->task_capacity = mpp->task_capacity;
1076
+
1077
+done:
9961078 mutex_unlock(&queue->dev_lock);
9971079 }
9981080
....@@ -1002,7 +1084,15 @@
10021084
10031085 if (queue) {
10041086 mutex_lock(&queue->dev_lock);
1087
+
1088
+ queue->cores[mpp->core_id] = NULL;
1089
+ queue->core_count--;
1090
+
1091
+ clear_bit(mpp->core_id, &queue->core_idle);
10051092 list_del_init(&mpp->queue_link);
1093
+
1094
+ mpp->queue = NULL;
1095
+
10061096 mutex_unlock(&queue->dev_lock);
10071097 }
10081098 }
....@@ -1018,27 +1108,6 @@
10181108 found = (cmd >= MPP_CMD_CONTROL_BASE && cmd < MPP_CMD_CONTROL_BUTT) ? true : found;
10191109
10201110 return found ? 0 : -EINVAL;
1021
-}
1022
-
1023
-static int mpp_parse_msg_v1(struct mpp_msg_v1 *msg,
1024
- struct mpp_request *req)
1025
-{
1026
- int ret = 0;
1027
-
1028
- req->cmd = msg->cmd;
1029
- req->flags = msg->flags;
1030
- req->size = msg->size;
1031
- req->offset = msg->offset;
1032
- req->data = (void __user *)(unsigned long)msg->data_ptr;
1033
-
1034
- mpp_debug(DEBUG_IOCTL, "cmd %x, flags %08x, size %d, offset %x\n",
1035
- req->cmd, req->flags, req->size, req->offset);
1036
-
1037
- ret = mpp_check_cmd_v1(req->cmd);
1038
- if (ret)
1039
- mpp_err("mpp cmd %x is not supproted.\n", req->cmd);
1040
-
1041
- return ret;
10421111 }
10431112
10441113 static inline int mpp_msg_is_last(struct mpp_request *req)
....@@ -1090,7 +1159,8 @@
10901159 int ret;
10911160 struct mpp_dev *mpp;
10921161
1093
- mpp_debug(DEBUG_IOCTL, "req->cmd %x\n", req->cmd);
1162
+ mpp_debug(DEBUG_IOCTL, "cmd %x process\n", req->cmd);
1163
+
10941164 switch (req->cmd) {
10951165 case MPP_CMD_QUERY_HW_SUPPORT: {
10961166 u32 hw_support = srv->hw_support;
....@@ -1116,8 +1186,10 @@
11161186 if (test_bit(client_type, &srv->hw_support))
11171187 mpp = srv->sub_devices[client_type];
11181188 }
1189
+
11191190 if (!mpp)
11201191 return -EINVAL;
1192
+
11211193 hw_info = mpp->var->hw_info;
11221194 mpp_debug(DEBUG_IOCTL, "hw_id %08x\n", hw_info->hw_id);
11231195 if (put_user(hw_info->hw_id, (u32 __user *)req->data))
....@@ -1148,6 +1220,7 @@
11481220 mpp = srv->sub_devices[client_type];
11491221 if (!mpp)
11501222 return -EINVAL;
1223
+
11511224 session->device_type = (enum MPP_DEVICE_TYPE)client_type;
11521225 session->dma = mpp_dma_session_create(mpp->dev, mpp->session_max_buffers);
11531226 session->mpp = mpp;
....@@ -1169,6 +1242,7 @@
11691242 if (ret)
11701243 return ret;
11711244 }
1245
+
11721246 mpp_session_attach_workqueue(session, mpp->queue);
11731247 } break;
11741248 case MPP_CMD_INIT_DRIVER_DATA: {
....@@ -1211,6 +1285,21 @@
12111285 case MPP_CMD_POLL_HW_FINISH: {
12121286 msgs->flags |= req->flags;
12131287 msgs->poll_cnt++;
1288
+ msgs->poll_req = NULL;
1289
+ } break;
1290
+ case MPP_CMD_POLL_HW_IRQ: {
1291
+ if (msgs->poll_cnt || msgs->poll_req)
1292
+ mpp_err("Do NOT poll hw irq when previous call not return\n");
1293
+
1294
+ msgs->flags |= req->flags;
1295
+ msgs->poll_cnt++;
1296
+
1297
+ if (req->size && req->data) {
1298
+ if (!msgs->poll_req)
1299
+ msgs->poll_req = req;
1300
+ } else {
1301
+ msgs->poll_req = NULL;
1302
+ }
12141303 } break;
12151304 case MPP_CMD_RESET_SESSION: {
12161305 int ret;
....@@ -1300,7 +1389,7 @@
13001389 default: {
13011390 mpp = session->mpp;
13021391 if (!mpp) {
1303
- mpp_err("pid %d not find clinet %d\n",
1392
+ mpp_err("pid %d not find client %d\n",
13041393 session->pid, session->device_type);
13051394 return -EINVAL;
13061395 }
....@@ -1314,17 +1403,228 @@
13141403 return 0;
13151404 }
13161405
1317
-static long mpp_dev_ioctl(struct file *filp,
1318
- unsigned int cmd,
1319
- unsigned long arg)
1406
+static void task_msgs_add(struct mpp_task_msgs *msgs, struct list_head *head)
13201407 {
1408
+ struct mpp_session *session = msgs->session;
13211409 int ret = 0;
1322
- struct mpp_service *srv;
1323
- void __user *msg;
1410
+
1411
+ /* process each task */
1412
+ if (msgs->set_cnt) {
1413
+ /* NOTE: update msg_flags for fd over 1024 */
1414
+ session->msg_flags = msgs->flags;
1415
+ ret = mpp_process_task(session, msgs);
1416
+ }
1417
+
1418
+ if (!ret) {
1419
+ INIT_LIST_HEAD(&msgs->list);
1420
+ list_add_tail(&msgs->list, head);
1421
+ } else {
1422
+ put_task_msgs(msgs);
1423
+ }
1424
+}
1425
+
1426
+static int mpp_collect_msgs(struct list_head *head, struct mpp_session *session,
1427
+ unsigned int cmd, void __user *msg)
1428
+{
1429
+ struct mpp_msg_v1 msg_v1;
13241430 struct mpp_request *req;
1325
- struct mpp_task_msgs task_msgs;
1326
- struct mpp_session *session =
1327
- (struct mpp_session *)filp->private_data;
1431
+ struct mpp_task_msgs *msgs = NULL;
1432
+ int last = 1;
1433
+ int ret;
1434
+
1435
+ if (cmd != MPP_IOC_CFG_V1) {
1436
+ mpp_err("unknown ioctl cmd %x\n", cmd);
1437
+ return -EINVAL;
1438
+ }
1439
+
1440
+next:
1441
+ /* first, parse to fixed struct */
1442
+ if (copy_from_user(&msg_v1, msg, sizeof(msg_v1)))
1443
+ return -EFAULT;
1444
+
1445
+ msg += sizeof(msg_v1);
1446
+
1447
+ mpp_debug(DEBUG_IOCTL, "cmd %x collect flags %08x, size %d, offset %x\n",
1448
+ msg_v1.cmd, msg_v1.flags, msg_v1.size, msg_v1.offset);
1449
+
1450
+ if (mpp_check_cmd_v1(msg_v1.cmd)) {
1451
+ mpp_err("mpp cmd %x is not supported.\n", msg_v1.cmd);
1452
+ return -EFAULT;
1453
+ }
1454
+
1455
+ if (msg_v1.flags & MPP_FLAGS_MULTI_MSG)
1456
+ last = (msg_v1.flags & MPP_FLAGS_LAST_MSG) ? 1 : 0;
1457
+ else
1458
+ last = 1;
1459
+
1460
+ /* check cmd for change msgs session */
1461
+ if (msg_v1.cmd == MPP_CMD_SET_SESSION_FD) {
1462
+ struct mpp_bat_msg bat_msg;
1463
+ struct mpp_bat_msg __user *usr_cmd;
1464
+ struct fd f;
1465
+
1466
+ /* try session switch here */
1467
+ usr_cmd = (struct mpp_bat_msg __user *)(unsigned long)msg_v1.data_ptr;
1468
+
1469
+ if (copy_from_user(&bat_msg, usr_cmd, sizeof(bat_msg)))
1470
+ return -EFAULT;
1471
+
1472
+ /* skip finished message */
1473
+ if (bat_msg.flag & MPP_BAT_MSG_DONE)
1474
+ goto session_switch_done;
1475
+
1476
+ f = fdget(bat_msg.fd);
1477
+ if (!f.file) {
1478
+ int ret = -EBADF;
1479
+
1480
+ mpp_err("fd %d get session failed\n", bat_msg.fd);
1481
+
1482
+ if (copy_to_user(&usr_cmd->ret, &ret, sizeof(usr_cmd->ret)))
1483
+ mpp_err("copy_to_user failed.\n");
1484
+ goto session_switch_done;
1485
+ }
1486
+
1487
+ /* NOTE: add previous ready task to queue and drop empty task */
1488
+ if (msgs) {
1489
+ if (msgs->req_cnt)
1490
+ task_msgs_add(msgs, head);
1491
+ else
1492
+ put_task_msgs(msgs);
1493
+
1494
+ msgs = NULL;
1495
+ }
1496
+
1497
+ /* switch session */
1498
+ session = f.file->private_data;
1499
+ msgs = get_task_msgs(session);
1500
+
1501
+ if (f.file->private_data == session)
1502
+ msgs->ext_fd = bat_msg.fd;
1503
+
1504
+ msgs->f = f;
1505
+
1506
+ mpp_debug(DEBUG_IOCTL, "fd %d, session %d msg_cnt %d\n",
1507
+ bat_msg.fd, session->index, session->msgs_cnt);
1508
+
1509
+session_switch_done:
1510
+ /* session id should NOT be the last message */
1511
+ if (last)
1512
+ return 0;
1513
+
1514
+ goto next;
1515
+ }
1516
+
1517
+ if (!msgs)
1518
+ msgs = get_task_msgs(session);
1519
+
1520
+ if (!msgs) {
1521
+ pr_err("session %d:%d failed to get task msgs",
1522
+ session->pid, session->index);
1523
+ return -EINVAL;
1524
+ }
1525
+
1526
+ if (msgs->req_cnt >= MPP_MAX_MSG_NUM) {
1527
+ mpp_err("session %d message count %d more than %d.\n",
1528
+ session->index, msgs->req_cnt, MPP_MAX_MSG_NUM);
1529
+ return -EINVAL;
1530
+ }
1531
+
1532
+ req = &msgs->reqs[msgs->req_cnt++];
1533
+ req->cmd = msg_v1.cmd;
1534
+ req->flags = msg_v1.flags;
1535
+ req->size = msg_v1.size;
1536
+ req->offset = msg_v1.offset;
1537
+ req->data = (void __user *)(unsigned long)msg_v1.data_ptr;
1538
+
1539
+ ret = mpp_process_request(session, session->srv, req, msgs);
1540
+ if (ret) {
1541
+ mpp_err("session %d process cmd %x ret %d\n",
1542
+ session->index, req->cmd, ret);
1543
+ return ret;
1544
+ }
1545
+
1546
+ if (!last)
1547
+ goto next;
1548
+
1549
+ task_msgs_add(msgs, head);
1550
+ msgs = NULL;
1551
+
1552
+ return 0;
1553
+}
1554
+
1555
+static void mpp_msgs_trigger(struct list_head *msgs_list)
1556
+{
1557
+ struct mpp_task_msgs *msgs, *n;
1558
+ struct mpp_dev *mpp_prev = NULL;
1559
+ struct mpp_taskqueue *queue_prev = NULL;
1560
+
1561
+ /* push task to queue */
1562
+ list_for_each_entry_safe(msgs, n, msgs_list, list) {
1563
+ struct mpp_dev *mpp;
1564
+ struct mpp_task *task;
1565
+ struct mpp_taskqueue *queue;
1566
+
1567
+ if (!msgs->set_cnt || !msgs->queue)
1568
+ continue;
1569
+
1570
+ mpp = msgs->mpp;
1571
+ task = msgs->task;
1572
+ queue = msgs->queue;
1573
+
1574
+ if (queue_prev != queue) {
1575
+ if (queue_prev && mpp_prev) {
1576
+ mutex_unlock(&queue_prev->pending_lock);
1577
+ mpp_taskqueue_trigger_work(mpp_prev);
1578
+ }
1579
+
1580
+ if (queue)
1581
+ mutex_lock(&queue->pending_lock);
1582
+
1583
+ mpp_prev = mpp;
1584
+ queue_prev = queue;
1585
+ }
1586
+
1587
+ if (test_bit(TASK_STATE_ABORT, &task->state))
1588
+ pr_info("try to trigger abort task %d\n", task->task_id);
1589
+
1590
+ set_bit(TASK_STATE_PENDING, &task->state);
1591
+ list_add_tail(&task->queue_link, &queue->pending_list);
1592
+ }
1593
+
1594
+ if (mpp_prev && queue_prev) {
1595
+ mutex_unlock(&queue_prev->pending_lock);
1596
+ mpp_taskqueue_trigger_work(mpp_prev);
1597
+ }
1598
+}
1599
+
1600
+static void mpp_msgs_wait(struct list_head *msgs_list)
1601
+{
1602
+ struct mpp_task_msgs *msgs, *n;
1603
+
1604
+ /* poll and release each task */
1605
+ list_for_each_entry_safe(msgs, n, msgs_list, list) {
1606
+ struct mpp_session *session = msgs->session;
1607
+
1608
+ if (msgs->poll_cnt) {
1609
+ int ret = mpp_wait_result(session, msgs);
1610
+
1611
+ if (ret) {
1612
+ mpp_err("session %d wait result ret %d\n",
1613
+ session->index, ret);
1614
+ }
1615
+ }
1616
+
1617
+ put_task_msgs(msgs);
1618
+
1619
+ }
1620
+}
1621
+
1622
+static long mpp_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1623
+{
1624
+ struct mpp_service *srv;
1625
+ struct mpp_session *session = (struct mpp_session *)filp->private_data;
1626
+ struct list_head msgs_list;
1627
+ int ret = 0;
13281628
13291629 mpp_debug_enter();
13301630
....@@ -1332,7 +1632,9 @@
13321632 mpp_err("session %p\n", session);
13331633 return -EINVAL;
13341634 }
1635
+
13351636 srv = session->srv;
1637
+
13361638 if (atomic_read(&session->release_request) > 0) {
13371639 mpp_debug(DEBUG_IOCTL, "release session had request\n");
13381640 return -EBUSY;
....@@ -1342,54 +1644,15 @@
13421644 return -EBUSY;
13431645 }
13441646
1345
- msg = (void __user *)arg;
1346
- memset(&task_msgs, 0, sizeof(task_msgs));
1347
- do {
1348
- req = &task_msgs.reqs[task_msgs.req_cnt];
1349
- /* first, parse to fixed struct */
1350
- switch (cmd) {
1351
- case MPP_IOC_CFG_V1: {
1352
- struct mpp_msg_v1 msg_v1;
1647
+ INIT_LIST_HEAD(&msgs_list);
13531648
1354
- memset(&msg_v1, 0, sizeof(msg_v1));
1355
- if (copy_from_user(&msg_v1, msg, sizeof(msg_v1)))
1356
- return -EFAULT;
1357
- ret = mpp_parse_msg_v1(&msg_v1, req);
1358
- if (ret)
1359
- return -EFAULT;
1649
+ ret = mpp_collect_msgs(&msgs_list, session, cmd, (void __user *)arg);
1650
+ if (ret)
1651
+ mpp_err("collect msgs failed %d\n", ret);
13601652
1361
- msg += sizeof(msg_v1);
1362
- } break;
1363
- default:
1364
- mpp_err("unknown ioctl cmd %x\n", cmd);
1365
- return -EINVAL;
1366
- }
1367
- task_msgs.req_cnt++;
1368
- /* check loop times */
1369
- if (task_msgs.req_cnt > MPP_MAX_MSG_NUM) {
1370
- mpp_err("fail, message count %d more than %d.\n",
1371
- task_msgs.req_cnt, MPP_MAX_MSG_NUM);
1372
- return -EINVAL;
1373
- }
1374
- /* second, process request */
1375
- ret = mpp_process_request(session, srv, req, &task_msgs);
1376
- if (ret)
1377
- return -EFAULT;
1378
- /* last, process task message */
1379
- if (mpp_msg_is_last(req)) {
1380
- session->msg_flags = task_msgs.flags;
1381
- if (task_msgs.set_cnt > 0) {
1382
- ret = mpp_process_task(session, &task_msgs);
1383
- if (ret)
1384
- return ret;
1385
- }
1386
- if (task_msgs.poll_cnt > 0) {
1387
- ret = mpp_wait_result(session, &task_msgs);
1388
- if (ret)
1389
- return ret;
1390
- }
1391
- }
1392
- } while (!mpp_msg_is_last(req));
1653
+ mpp_msgs_trigger(&msgs_list);
1654
+
1655
+ mpp_msgs_wait(&msgs_list);
13931656
13941657 mpp_debug_leave();
13951658
....@@ -1493,9 +1756,9 @@
14931756 mpp_iommu_down_read(mpp->iommu_info);
14941757 buffer = mpp_dma_import_fd(mpp->iommu_info, dma, fd);
14951758 mpp_iommu_up_read(mpp->iommu_info);
1496
- if (IS_ERR_OR_NULL(buffer)) {
1759
+ if (IS_ERR(buffer)) {
14971760 mpp_err("can't import dma-buf %d\n", fd);
1498
- return ERR_PTR(-ENOMEM);
1761
+ return ERR_CAST(buffer);
14991762 }
15001763
15011764 mem_region->hdl = buffer;
....@@ -1525,7 +1788,7 @@
15251788 cnt = session->trans_count;
15261789 tbl = session->trans_table;
15271790 } else {
1528
- struct mpp_dev *mpp = session->mpp;
1791
+ struct mpp_dev *mpp = mpp_get_task_used_device(task, session);
15291792 struct mpp_trans_info *trans_info = mpp->var->trans_info;
15301793
15311794 cnt = trans_info[fmt].count;
....@@ -1661,8 +1924,7 @@
16611924 return 0;
16621925 }
16631926
1664
-int mpp_task_init(struct mpp_session *session,
1665
- struct mpp_task *task)
1927
+int mpp_task_init(struct mpp_session *session, struct mpp_task *task)
16661928 {
16671929 INIT_LIST_HEAD(&task->pending_link);
16681930 INIT_LIST_HEAD(&task->queue_link);
....@@ -1677,7 +1939,7 @@
16771939 int mpp_task_finish(struct mpp_session *session,
16781940 struct mpp_task *task)
16791941 {
1680
- struct mpp_dev *mpp = session->mpp;
1942
+ struct mpp_dev *mpp = mpp_get_task_used_device(task, session);
16811943
16821944 if (mpp->dev_ops->finish)
16831945 mpp->dev_ops->finish(mpp, task);
....@@ -1713,7 +1975,7 @@
17131975 struct mpp_task *task)
17141976 {
17151977 struct mpp_mem_region *mem_region = NULL, *n;
1716
- struct mpp_dev *mpp = session->mpp;
1978
+ struct mpp_dev *mpp = mpp_get_task_used_device(task, session);
17171979
17181980 /* release memory region attach to this registers table. */
17191981 list_for_each_entry_safe(mem_region, n,
....@@ -1738,7 +2000,7 @@
17382000 if (!task)
17392001 return -EIO;
17402002
1741
- mpp_err("--- dump mem region ---\n");
2003
+ mpp_err("--- dump task %d mem region ---\n", task->task_index);
17422004 if (!list_empty(&task->mem_region_list)) {
17432005 list_for_each_entry_safe(mem, n,
17442006 &task->mem_region_list,
....@@ -1778,54 +2040,41 @@
17782040 return 0;
17792041 }
17802042
1781
-int mpp_task_dump_hw_reg(struct mpp_dev *mpp, struct mpp_task *task)
2043
+int mpp_task_dump_hw_reg(struct mpp_dev *mpp)
17822044 {
1783
- if (!task)
1784
- return -EIO;
2045
+ u32 i;
2046
+ u32 s = mpp->var->hw_info->reg_start;
2047
+ u32 e = mpp->var->hw_info->reg_end;
17852048
1786
- if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG)) {
1787
- u32 i;
1788
- u32 s = task->hw_info->reg_start;
1789
- u32 e = task->hw_info->reg_end;
2049
+ mpp_err("--- dump hardware register ---\n");
2050
+ for (i = s; i <= e; i++) {
2051
+ u32 reg = i * sizeof(u32);
17902052
1791
- mpp_err("--- dump hardware register ---\n");
1792
- for (i = s; i <= e; i++) {
1793
- u32 reg = i * sizeof(u32);
1794
-
1795
- mpp_err("reg[%03d]: %04x: 0x%08x\n",
2053
+ mpp_err("reg[%03d]: %04x: 0x%08x\n",
17962054 i, reg, readl_relaxed(mpp->reg_base + reg));
1797
- }
17982055 }
17992056
18002057 return 0;
18012058 }
18022059
1803
-static int mpp_iommu_handle(struct iommu_domain *iommu,
1804
- struct device *iommu_dev,
1805
- unsigned long iova,
1806
- int status, void *arg)
2060
+void mpp_reg_show(struct mpp_dev *mpp, u32 offset)
18072061 {
1808
- struct mpp_dev *mpp = (struct mpp_dev *)arg;
1809
- struct mpp_taskqueue *queue = mpp->queue;
1810
- struct mpp_task *task = mpp_taskqueue_get_running_task(queue);
2062
+ if (!mpp)
2063
+ return;
18112064
1812
- /*
1813
- * NOTE: In link mode, this task may not be the task of the current
1814
- * hardware processing error
1815
- */
1816
- if (!task || !task->session)
1817
- return -EIO;
1818
- /* get mpp from cur task */
1819
- mpp = task->session->mpp;
1820
- dev_err(mpp->dev, "fault addr 0x%08lx status %x\n", iova, status);
2065
+ dev_err(mpp->dev, "reg[%03d]: %04x: 0x%08x\n",
2066
+ offset >> 2, offset, mpp_read_relaxed(mpp, offset));
2067
+}
18212068
1822
- mpp_task_dump_mem_region(mpp, task);
1823
- mpp_task_dump_hw_reg(mpp, task);
2069
+void mpp_reg_show_range(struct mpp_dev *mpp, u32 start, u32 end)
2070
+{
2071
+ u32 offset;
18242072
1825
- if (mpp->iommu_info->hdl)
1826
- mpp->iommu_info->hdl(iommu, iommu_dev, iova, status, mpp);
2073
+ if (!mpp)
2074
+ return;
18272075
1828
- return 0;
2076
+ for (offset = start; offset < end; offset += sizeof(u32))
2077
+ mpp_reg_show(mpp, offset);
18292078 }
18302079
18312080 /* The device will do more probing work after this */
....@@ -1843,6 +2092,16 @@
18432092 /* read flag for pum idle request */
18442093 mpp->skip_idle = device_property_read_bool(dev, "rockchip,skip-pmu-idle-request");
18452094
2095
+ /* read link table capacity */
2096
+ ret = of_property_read_u32(np, "rockchip,task-capacity",
2097
+ &mpp->task_capacity);
2098
+ if (ret)
2099
+ mpp->task_capacity = 1;
2100
+
2101
+ mpp->dev = dev;
2102
+ mpp->hw_ops = mpp->var->hw_ops;
2103
+ mpp->dev_ops = mpp->var->dev_ops;
2104
+
18462105 /* Get and attach to service */
18472106 ret = mpp_attach_service(mpp, dev);
18482107 if (ret) {
....@@ -1850,24 +2109,9 @@
18502109 return -ENODEV;
18512110 }
18522111
1853
- mpp->dev = dev;
1854
- mpp->hw_ops = mpp->var->hw_ops;
1855
- mpp->dev_ops = mpp->var->dev_ops;
1856
-
1857
- /* read link table capacity */
1858
- ret = of_property_read_u32(np, "rockchip,task-capacity",
1859
- &mpp->task_capacity);
1860
- if (ret) {
1861
- mpp->task_capacity = 1;
1862
-
1863
- /* power domain autosuspend delay 2s */
1864
- pm_runtime_set_autosuspend_delay(dev, 2000);
1865
- pm_runtime_use_autosuspend(dev);
1866
- } else {
1867
- dev_info(dev, "%d task capacity link mode detected\n",
1868
- mpp->task_capacity);
1869
- /* do not setup autosuspend on multi task device */
1870
- }
2112
+ /* power domain autosuspend delay 2s */
2113
+ pm_runtime_set_autosuspend_delay(dev, 2000);
2114
+ pm_runtime_use_autosuspend(dev);
18712115
18722116 kthread_init_work(&mpp->work, mpp_task_worker_default);
18732117
....@@ -1878,7 +2122,6 @@
18782122
18792123 device_init_wakeup(dev, true);
18802124 pm_runtime_enable(dev);
1881
-
18822125 mpp->irq = platform_get_irq(pdev, 0);
18832126 if (mpp->irq < 0) {
18842127 dev_err(dev, "No interrupt resource found\n");
....@@ -1905,42 +2148,36 @@
19052148 ret = -ENOMEM;
19062149 goto failed;
19072150 }
2151
+ mpp->io_base = res->start;
19082152
1909
- pm_runtime_get_sync(dev);
19102153 /*
19112154 * TODO: here or at the device itself, some device does not
19122155 * have the iommu, maybe in the device is better.
19132156 */
19142157 mpp->iommu_info = mpp_iommu_probe(dev);
19152158 if (IS_ERR(mpp->iommu_info)) {
1916
- dev_err(dev, "failed to attach iommu: %ld\n",
1917
- PTR_ERR(mpp->iommu_info));
2159
+ dev_err(dev, "failed to attach iommu\n");
2160
+ mpp->iommu_info = NULL;
19182161 }
19192162 if (mpp->hw_ops->init) {
19202163 ret = mpp->hw_ops->init(mpp);
19212164 if (ret)
1922
- goto failed_init;
2165
+ goto failed;
19232166 }
1924
- /* set iommu fault handler */
1925
- if (!IS_ERR(mpp->iommu_info))
1926
- iommu_set_fault_handler(mpp->iommu_info->domain,
1927
- mpp_iommu_handle, mpp);
19282167
19292168 /* read hardware id */
19302169 if (hw_info->reg_id >= 0) {
2170
+ pm_runtime_get_sync(dev);
19312171 if (mpp->hw_ops->clk_on)
19322172 mpp->hw_ops->clk_on(mpp);
19332173
19342174 hw_info->hw_id = mpp_read(mpp, hw_info->reg_id * sizeof(u32));
19352175 if (mpp->hw_ops->clk_off)
19362176 mpp->hw_ops->clk_off(mpp);
2177
+ pm_runtime_put_sync(dev);
19372178 }
19382179
1939
- pm_runtime_put_sync(dev);
1940
-
19412180 return ret;
1942
-failed_init:
1943
- pm_runtime_put_sync(dev);
19442181 failed:
19452182 mpp_detach_workqueue(mpp);
19462183 device_init_wakeup(dev, false);
....@@ -1955,12 +2192,31 @@
19552192 mpp->hw_ops->exit(mpp);
19562193
19572194 mpp_iommu_remove(mpp->iommu_info);
1958
- platform_device_put(mpp->pdev_srv);
19592195 mpp_detach_workqueue(mpp);
19602196 device_init_wakeup(mpp->dev, false);
19612197 pm_runtime_disable(mpp->dev);
19622198
19632199 return 0;
2200
+}
2201
+
2202
+void mpp_dev_shutdown(struct platform_device *pdev)
2203
+{
2204
+ int ret;
2205
+ int val;
2206
+ struct device *dev = &pdev->dev;
2207
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
2208
+
2209
+ dev_info(dev, "shutdown device\n");
2210
+
2211
+ atomic_inc(&mpp->srv->shutdown_request);
2212
+ ret = readx_poll_timeout(atomic_read,
2213
+ &mpp->task_count,
2214
+ val, val == 0, 20000, 200000);
2215
+ if (ret == -ETIMEDOUT)
2216
+ dev_err(dev, "wait total %d running time out\n",
2217
+ atomic_read(&mpp->task_count));
2218
+ else
2219
+ dev_info(dev, "shutdown success\n");
19642220 }
19652221
19662222 int mpp_dev_register_srv(struct mpp_dev *mpp, struct mpp_service *srv)
....@@ -1989,7 +2245,7 @@
19892245 irq_ret = mpp->dev_ops->irq(mpp);
19902246
19912247 if (task) {
1992
- if (irq_ret != IRQ_NONE) {
2248
+ if (irq_ret == IRQ_WAKE_THREAD) {
19932249 /* if wait or delayed work timeout, abort request will turn on,
19942250 * isr should not to response, and handle it in delayed work
19952251 */
....@@ -2007,6 +2263,9 @@
20072263 /* normal condition, set state and wake up isr thread */
20082264 set_bit(TASK_STATE_IRQ, &task->state);
20092265 }
2266
+
2267
+ if (irq_ret == IRQ_WAKE_THREAD)
2268
+ mpp_iommu_dev_deactivate(mpp->iommu_info, mpp);
20102269 } else {
20112270 mpp_debug(DEBUG_IRQ_CHECK, "error, task is null\n");
20122271 }
....@@ -2083,27 +2342,31 @@
20832342
20842343 int mpp_time_part_diff(struct mpp_task *task)
20852344 {
2086
- ktime_t end;
2087
- struct mpp_dev *mpp = task->session->mpp;
2345
+ if (mpp_debug_unlikely(DEBUG_TIMING)) {
2346
+ ktime_t end;
2347
+ struct mpp_dev *mpp = mpp_get_task_used_device(task, task->session);
20882348
2089
- end = ktime_get();
2090
- mpp_debug(DEBUG_PART_TIMING, "%s: session %d:%d part time: %lld us\n",
2091
- dev_name(mpp->dev), task->session->pid, task->session->index,
2092
- ktime_us_delta(end, task->part));
2093
- task->part = end;
2349
+ end = ktime_get();
2350
+ mpp_debug(DEBUG_PART_TIMING, "%s:%d session %d:%d part time: %lld us\n",
2351
+ dev_name(mpp->dev), task->core_id, task->session->pid,
2352
+ task->session->index, ktime_us_delta(end, task->part));
2353
+ task->part = end;
2354
+ }
20942355
20952356 return 0;
20962357 }
20972358
20982359 int mpp_time_diff(struct mpp_task *task)
20992360 {
2100
- ktime_t end;
2101
- struct mpp_dev *mpp = task->session->mpp;
2361
+ if (mpp_debug_unlikely(DEBUG_TIMING)) {
2362
+ ktime_t end;
2363
+ struct mpp_dev *mpp = mpp_get_task_used_device(task, task->session);
21022364
2103
- end = ktime_get();
2104
- mpp_debug(DEBUG_TIMING, "%s: session %d:%d task time: %lld us\n",
2105
- dev_name(mpp->dev), task->session->pid, task->session->index,
2106
- ktime_us_delta(end, task->start));
2365
+ end = ktime_get();
2366
+ mpp_debug(DEBUG_TIMING, "%s:%d session %d:%d time: %lld us\n",
2367
+ dev_name(mpp->dev), task->core_id, task->session->pid,
2368
+ task->session->index, ktime_us_delta(end, task->start));
2369
+ }
21072370
21082371 return 0;
21092372 }
....@@ -2112,19 +2375,19 @@
21122375 {
21132376 if (mpp_debug_unlikely(DEBUG_TIMING)) {
21142377 ktime_t end;
2115
- struct mpp_dev *mpp = task->session->mpp;
2378
+ struct mpp_dev *mpp = mpp_get_task_used_device(task, task->session);
21162379
21172380 end = ktime_get();
21182381
21192382 if (clk_hz)
2120
- mpp_debug(DEBUG_TIMING, "%s: session %d time: %lld us hw %d us\n",
2121
- dev_name(mpp->dev), task->session->index,
2122
- ktime_us_delta(end, task->start),
2383
+ mpp_debug(DEBUG_TIMING, "%s:%d session %d:%d time: %lld us hw %d us\n",
2384
+ dev_name(mpp->dev), task->core_id, task->session->pid,
2385
+ task->session->index, ktime_us_delta(end, task->start),
21232386 task->hw_cycles / (clk_hz / 1000000));
21242387 else
2125
- mpp_debug(DEBUG_TIMING, "%s: session %d time: %lld us\n",
2126
- dev_name(mpp->dev), task->session->index,
2127
- ktime_us_delta(end, task->start));
2388
+ mpp_debug(DEBUG_TIMING, "%s:%d session %d:%d time: %lld us\n",
2389
+ dev_name(mpp->dev), task->core_id, task->session->pid,
2390
+ task->session->index, ktime_us_delta(end, task->start));
21282391 }
21292392
21302393 return 0;
....@@ -2143,7 +2406,7 @@
21432406 ktime_t s = task->on_create;
21442407 unsigned long state = task->state;
21452408
2146
- pr_info("task %d dump timing at %lld us:", task->task_index, time_diff);
2409
+ pr_info("task %d dump timing at %lld us:", task->task_id, time_diff);
21472410
21482411 pr_info("timing: %-14s : %lld us\n", "create", ktime_to_us(s));
21492412 LOG_TIMING(state, TASK_TIMING_CREATE_END, "create end", task->on_create_end, s);
....@@ -2325,11 +2588,11 @@
23252588 return count;
23262589 }
23272590
2328
-static const struct file_operations procfs_fops_u32 = {
2329
- .open = fops_open_u32,
2330
- .read = seq_read,
2331
- .release = single_release,
2332
- .write = fops_write_u32,
2591
+static const struct proc_ops procfs_fops_u32 = {
2592
+ .proc_open = fops_open_u32,
2593
+ .proc_read = seq_read,
2594
+ .proc_release = single_release,
2595
+ .proc_write = fops_write_u32,
23332596 };
23342597
23352598 struct proc_dir_entry *
....@@ -2341,6 +2604,7 @@
23412604
23422605 void mpp_procfs_create_common(struct proc_dir_entry *parent, struct mpp_dev *mpp)
23432606 {
2607
+ mpp_procfs_create_u32("disable_work", 0644, parent, &mpp->disable);
23442608 mpp_procfs_create_u32("timing_check", 0644, parent, &mpp->timing_check);
23452609 }
23462610 #endif