hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/video/rockchip/mpp/mpp_vepu2.c
....@@ -36,6 +36,8 @@
3636 #define VEPU2_REG_HW_ID_INDEX -1 /* INVALID */
3737 #define VEPU2_REG_START_INDEX 0
3838 #define VEPU2_REG_END_INDEX 183
39
+#define VEPU2_REG_OUT_INDEX (77)
40
+#define VEPU2_REG_STRM_INDEX (53)
3941
4042 #define VEPU2_REG_ENC_EN 0x19c
4143 #define VEPU2_REG_ENC_EN_INDEX (103)
....@@ -97,6 +99,8 @@
9799 u32 width;
98100 u32 height;
99101 u32 pixels;
102
+ struct mpp_dma_buffer *bs_buf;
103
+ u32 offset_bs;
100104 };
101105
102106 struct vepu_session_priv {
....@@ -121,6 +125,18 @@
121125 #endif
122126 struct reset_control *rst_a;
123127 struct reset_control *rst_h;
128
+ /* for ccu(central control unit) */
129
+ struct vepu_ccu *ccu;
130
+ bool disable_work;
131
+};
132
+
133
+struct vepu_ccu {
134
+ u32 core_num;
135
+ /* lock for core attach */
136
+ spinlock_t lock;
137
+ struct mpp_dev *main_core;
138
+ struct mpp_dev *cores[MPP_MAX_CORE_NUM];
139
+ unsigned long core_idle;
124140 };
125141
126142 static struct mpp_hw_info vepu_v2_hw_info = {
....@@ -167,7 +183,13 @@
167183 struct mpp_task_msgs *msgs)
168184 {
169185 int ret;
186
+ int fd_bs;
170187 int fmt = VEPU2_GET_FORMAT(task->reg[VEPU2_REG_ENC_EN_INDEX]);
188
+
189
+ if (session->msg_flags & MPP_FLAGS_REG_NO_OFFSET)
190
+ fd_bs = task->reg[VEPU2_REG_OUT_INDEX];
191
+ else
192
+ fd_bs = task->reg[VEPU2_REG_OUT_INDEX] & 0x3ff;
171193
172194 ret = mpp_translate_reg_address(session, &task->mpp_task,
173195 fmt, task->reg, &task->off_inf);
....@@ -176,6 +198,15 @@
176198
177199 mpp_translate_reg_offset_info(&task->mpp_task,
178200 &task->off_inf, task->reg);
201
+
202
+ if (fmt == VEPU2_FMT_JPEGE) {
203
+ struct mpp_dma_buffer *bs_buf = mpp_dma_find_buffer_fd(session->dma, fd_bs);
204
+
205
+ task->offset_bs = mpp_query_reg_offset_info(&task->off_inf, VEPU2_REG_OUT_INDEX);
206
+ if (bs_buf && task->offset_bs > 0)
207
+ mpp_dma_buf_sync(bs_buf, 0, task->offset_bs, DMA_TO_DEVICE, false);
208
+ task->bs_buf = bs_buf;
209
+ }
179210
180211 return 0;
181212 }
....@@ -281,6 +312,50 @@
281312 return NULL;
282313 }
283314
315
+static void *vepu_prepare(struct mpp_dev *mpp, struct mpp_task *mpp_task)
316
+{
317
+ struct mpp_taskqueue *queue = mpp->queue;
318
+ struct vepu_dev *enc = to_vepu_dev(mpp);
319
+ struct vepu_ccu *ccu = enc->ccu;
320
+ unsigned long core_idle;
321
+ unsigned long flags;
322
+ u32 core_id_max;
323
+ s32 core_id;
324
+ u32 i;
325
+
326
+ spin_lock_irqsave(&ccu->lock, flags);
327
+
328
+ core_idle = queue->core_idle;
329
+ core_id_max = queue->core_id_max;
330
+
331
+ for (i = 0; i <= core_id_max; i++) {
332
+ struct mpp_dev *mpp = queue->cores[i];
333
+
334
+ if (mpp && mpp->disable)
335
+ clear_bit(i, &core_idle);
336
+ }
337
+
338
+ core_id = find_first_bit(&ccu->core_idle, ccu->core_num);
339
+ core_id = array_index_nospec(core_id, MPP_MAX_CORE_NUM);
340
+ if (core_id >= core_id_max + 1 || !queue->cores[core_id]) {
341
+ mpp_task = NULL;
342
+ mpp_dbg_core("core %d all busy %lx\n", core_id, ccu->core_idle);
343
+ } else {
344
+ unsigned long core_idle = ccu->core_idle;
345
+
346
+ clear_bit(core_id, &ccu->core_idle);
347
+ mpp_task->mpp = ccu->cores[core_id];
348
+ mpp_task->core_id = core_id;
349
+
350
+ mpp_dbg_core("core cnt %d core %d set idle %lx -> %lx\n",
351
+ ccu->core_num, core_id, core_idle, ccu->core_idle);
352
+ }
353
+
354
+ spin_unlock_irqrestore(&ccu->lock, flags);
355
+
356
+ return mpp_task;
357
+}
358
+
284359 static int vepu_run(struct mpp_dev *mpp,
285360 struct mpp_task *mpp_task)
286361 {
....@@ -327,6 +402,13 @@
327402 return 0;
328403 }
329404
405
+static int vepu_px30_run(struct mpp_dev *mpp,
406
+ struct mpp_task *mpp_task)
407
+{
408
+ mpp_iommu_flush_tlb(mpp->iommu_info);
409
+ return vepu_run(mpp, mpp_task);
410
+}
411
+
330412 static int vepu_irq(struct mpp_dev *mpp)
331413 {
332414 mpp->irq_status = mpp_read(mpp, VEPU2_REG_INT);
....@@ -343,6 +425,9 @@
343425 u32 err_mask;
344426 struct vepu_task *task = NULL;
345427 struct mpp_task *mpp_task = mpp->cur_task;
428
+ unsigned long core_idle;
429
+ struct vepu_dev *enc = to_vepu_dev(mpp);
430
+ struct vepu_ccu *ccu = enc->ccu;
346431
347432 /* FIXME use a spin lock here */
348433 if (!mpp_task) {
....@@ -364,6 +449,14 @@
364449 atomic_inc(&mpp->reset_request);
365450
366451 mpp_task_finish(mpp_task->session, mpp_task);
452
+ /* the whole vepu has no ccu that manage multi core */
453
+ if (ccu) {
454
+ core_idle = ccu->core_idle;
455
+ set_bit(mpp->core_id, &ccu->core_idle);
456
+
457
+ mpp_dbg_core("core %d isr idle %lx -> %lx\n", mpp->core_id, core_idle,
458
+ ccu->core_idle);
459
+ }
367460
368461 mpp_debug_leave();
369462
....@@ -390,6 +483,11 @@
390483 /* revert hack for irq status */
391484 task->reg[VEPU2_REG_INT_INDEX] = task->irq_status;
392485
486
+ if (task->bs_buf)
487
+ mpp_dma_buf_sync(task->bs_buf, 0,
488
+ task->reg[VEPU2_REG_STRM_INDEX] / 8 +
489
+ task->offset_bs,
490
+ DMA_FROM_DEVICE, true);
393491 mpp_debug_leave();
394492
395493 return 0;
....@@ -532,7 +630,7 @@
532630 }
533631 seq_puts(seq, "\n");
534632 /* item data*/
535
- seq_printf(seq, "|%8p|", session);
633
+ seq_printf(seq, "|%8d|", session->index);
536634 seq_printf(seq, "%8s|", mpp_device_name[session->device_type]);
537635 for (i = ENC_INFO_BASE; i < ENC_INFO_BUTT; i++) {
538636 u32 flag = priv->codec_info[i].flag;
....@@ -565,8 +663,9 @@
565663 mutex_lock(&mpp->srv->session_lock);
566664 list_for_each_entry_safe(session, n,
567665 &mpp->srv->session_list,
568
- session_link) {
569
- if (session->device_type != MPP_DEVICE_VEPU2)
666
+ service_link) {
667
+ if (session->device_type != MPP_DEVICE_VEPU2 &&
668
+ session->device_type != MPP_DEVICE_VEPU2_JPEG)
570669 continue;
571670 if (!session->priv)
572671 continue;
....@@ -581,8 +680,19 @@
581680 static int vepu_procfs_init(struct mpp_dev *mpp)
582681 {
583682 struct vepu_dev *enc = to_vepu_dev(mpp);
683
+ char name[32];
584684
585
- enc->procfs = proc_mkdir(mpp->dev->of_node->name, mpp->srv->procfs);
685
+ if (!mpp->dev || !mpp->dev->of_node || !mpp->dev->of_node->name ||
686
+ !mpp->srv || !mpp->srv->procfs)
687
+ return -EINVAL;
688
+ if (enc->ccu)
689
+ snprintf(name, sizeof(name) - 1, "%s%d",
690
+ mpp->dev->of_node->name, mpp->core_id);
691
+ else
692
+ snprintf(name, sizeof(name) - 1, "%s",
693
+ mpp->dev->of_node->name);
694
+
695
+ enc->procfs = proc_mkdir(name, mpp->srv->procfs);
586696 if (IS_ERR_OR_NULL(enc->procfs)) {
587697 mpp_err("failed on open procfs\n");
588698 enc->procfs = NULL;
....@@ -602,6 +712,17 @@
602712
603713 return 0;
604714 }
715
+
716
+static int vepu_procfs_ccu_init(struct mpp_dev *mpp)
717
+{
718
+ struct vepu_dev *enc = to_vepu_dev(mpp);
719
+
720
+ if (!enc->procfs)
721
+ goto done;
722
+
723
+done:
724
+ return 0;
725
+}
605726 #else
606727 static inline int vepu_procfs_remove(struct mpp_dev *mpp)
607728 {
....@@ -609,6 +730,11 @@
609730 }
610731
611732 static inline int vepu_procfs_init(struct mpp_dev *mpp)
733
+{
734
+ return 0;
735
+}
736
+
737
+static inline int vepu_procfs_ccu_init(struct mpp_dev *mpp)
612738 {
613739 return 0;
614740 }
....@@ -735,6 +861,7 @@
735861 static int vepu_reset(struct mpp_dev *mpp)
736862 {
737863 struct vepu_dev *enc = to_vepu_dev(mpp);
864
+ struct vepu_ccu *ccu = enc->ccu;
738865
739866 mpp_write(mpp, VEPU2_REG_ENC_EN, 0);
740867 udelay(5);
....@@ -749,6 +876,11 @@
749876 mpp_pmu_idle_request(mpp, false);
750877 }
751878 mpp_write(mpp, VEPU2_REG_INT, VEPU2_INT_CLEAR);
879
+
880
+ if (ccu) {
881
+ set_bit(mpp->core_id, &ccu->core_idle);
882
+ mpp_dbg_core("core %d reset idle %lx\n", mpp->core_id, ccu->core_idle);
883
+ }
752884
753885 return 0;
754886 }
....@@ -787,6 +919,36 @@
787919 .dump_session = vepu_dump_session,
788920 };
789921
922
+static struct mpp_dev_ops vepu_px30_dev_ops = {
923
+ .alloc_task = vepu_alloc_task,
924
+ .run = vepu_px30_run,
925
+ .irq = vepu_irq,
926
+ .isr = vepu_isr,
927
+ .finish = vepu_finish,
928
+ .result = vepu_result,
929
+ .free_task = vepu_free_task,
930
+ .ioctl = vepu_control,
931
+ .init_session = vepu_init_session,
932
+ .free_session = vepu_free_session,
933
+ .dump_session = vepu_dump_session,
934
+};
935
+
936
+static struct mpp_dev_ops vepu_ccu_dev_ops = {
937
+ .alloc_task = vepu_alloc_task,
938
+ .prepare = vepu_prepare,
939
+ .run = vepu_run,
940
+ .irq = vepu_irq,
941
+ .isr = vepu_isr,
942
+ .finish = vepu_finish,
943
+ .result = vepu_result,
944
+ .free_task = vepu_free_task,
945
+ .ioctl = vepu_control,
946
+ .init_session = vepu_init_session,
947
+ .free_session = vepu_free_session,
948
+ .dump_session = vepu_dump_session,
949
+};
950
+
951
+
790952 static const struct mpp_dev_var vepu_v2_data = {
791953 .device_type = MPP_DEVICE_VEPU2,
792954 .hw_info = &vepu_v2_hw_info,
....@@ -800,7 +962,15 @@
800962 .hw_info = &vepu_v2_hw_info,
801963 .trans_info = trans_rk_vepu2,
802964 .hw_ops = &vepu_px30_hw_ops,
803
- .dev_ops = &vepu_v2_dev_ops,
965
+ .dev_ops = &vepu_px30_dev_ops,
966
+};
967
+
968
+static const struct mpp_dev_var vepu_ccu_data = {
969
+ .device_type = MPP_DEVICE_VEPU2_JPEG,
970
+ .hw_info = &vepu_v2_hw_info,
971
+ .trans_info = trans_rk_vepu2,
972
+ .hw_ops = &vepu_v2_hw_ops,
973
+ .dev_ops = &vepu_ccu_dev_ops,
804974 };
805975
806976 static const struct of_device_id mpp_vepu2_dt_match[] = {
....@@ -814,10 +984,82 @@
814984 .data = &vepu_px30_data,
815985 },
816986 #endif
987
+#ifdef CONFIG_CPU_RK3588
988
+ {
989
+ .compatible = "rockchip,vpu-jpege-core",
990
+ .data = &vepu_ccu_data,
991
+ },
992
+ {
993
+ .compatible = "rockchip,vpu-jpege-ccu",
994
+ },
995
+#endif
817996 {},
818997 };
819998
820
-static int vepu_probe(struct platform_device *pdev)
999
+static int vepu_ccu_probe(struct platform_device *pdev)
1000
+{
1001
+ struct vepu_ccu *ccu;
1002
+ struct device *dev = &pdev->dev;
1003
+
1004
+ ccu = devm_kzalloc(dev, sizeof(*ccu), GFP_KERNEL);
1005
+ if (!ccu)
1006
+ return -ENOMEM;
1007
+
1008
+ platform_set_drvdata(pdev, ccu);
1009
+ spin_lock_init(&ccu->lock);
1010
+ return 0;
1011
+}
1012
+
1013
+static int vepu_attach_ccu(struct device *dev, struct vepu_dev *enc)
1014
+{
1015
+ struct device_node *np;
1016
+ struct platform_device *pdev;
1017
+ struct vepu_ccu *ccu;
1018
+ unsigned long flags;
1019
+
1020
+ np = of_parse_phandle(dev->of_node, "rockchip,ccu", 0);
1021
+ if (!np || !of_device_is_available(np))
1022
+ return -ENODEV;
1023
+
1024
+ pdev = of_find_device_by_node(np);
1025
+ of_node_put(np);
1026
+ if (!pdev)
1027
+ return -ENODEV;
1028
+
1029
+ ccu = platform_get_drvdata(pdev);
1030
+ if (!ccu)
1031
+ return -ENOMEM;
1032
+
1033
+ spin_lock_irqsave(&ccu->lock, flags);
1034
+ ccu->core_num++;
1035
+ ccu->cores[enc->mpp.core_id] = &enc->mpp;
1036
+ set_bit(enc->mpp.core_id, &ccu->core_idle);
1037
+ spin_unlock_irqrestore(&ccu->lock, flags);
1038
+
1039
+ /* attach the ccu-domain to current core */
1040
+ if (!ccu->main_core) {
1041
+ /**
1042
+ * set the first device for the main-core,
1043
+ * then the domain of the main-core named ccu-domain
1044
+ */
1045
+ ccu->main_core = &enc->mpp;
1046
+ } else {
1047
+ struct mpp_iommu_info *ccu_info, *cur_info;
1048
+
1049
+ /* set the ccu domain for current device */
1050
+ ccu_info = ccu->main_core->iommu_info;
1051
+ cur_info = enc->mpp.iommu_info;
1052
+
1053
+ cur_info->domain = ccu_info->domain;
1054
+ mpp_iommu_attach(cur_info);
1055
+ }
1056
+ enc->ccu = ccu;
1057
+
1058
+ dev_info(dev, "attach ccu success\n");
1059
+ return 0;
1060
+}
1061
+
1062
+static int vepu_core_probe(struct platform_device *pdev)
8211063 {
8221064 struct device *dev = &pdev->dev;
8231065 struct vepu_dev *enc = NULL;
....@@ -825,18 +1067,72 @@
8251067 const struct of_device_id *match = NULL;
8261068 int ret = 0;
8271069
828
- dev_info(dev, "probe device\n");
8291070 enc = devm_kzalloc(dev, sizeof(struct vepu_dev), GFP_KERNEL);
8301071 if (!enc)
8311072 return -ENOMEM;
8321073
8331074 mpp = &enc->mpp;
834
- platform_set_drvdata(pdev, enc);
1075
+ platform_set_drvdata(pdev, mpp);
8351076
8361077 if (pdev->dev.of_node) {
8371078 match = of_match_node(mpp_vepu2_dt_match, pdev->dev.of_node);
8381079 if (match)
8391080 mpp->var = (struct mpp_dev_var *)match->data;
1081
+
1082
+ mpp->core_id = of_alias_get_id(pdev->dev.of_node, "jpege");
1083
+ }
1084
+
1085
+ ret = mpp_dev_probe(mpp, pdev);
1086
+ if (ret) {
1087
+ dev_err(dev, "probe sub driver failed\n");
1088
+ return -EINVAL;
1089
+ }
1090
+ /* current device attach to ccu */
1091
+ ret = vepu_attach_ccu(dev, enc);
1092
+ if (ret)
1093
+ return ret;
1094
+
1095
+ ret = devm_request_threaded_irq(dev, mpp->irq,
1096
+ mpp_dev_irq,
1097
+ mpp_dev_isr_sched,
1098
+ IRQF_SHARED,
1099
+ dev_name(dev), mpp);
1100
+ if (ret) {
1101
+ dev_err(dev, "register interrupter runtime failed\n");
1102
+ return -EINVAL;
1103
+ }
1104
+
1105
+ mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
1106
+ vepu_procfs_init(mpp);
1107
+ vepu_procfs_ccu_init(mpp);
1108
+ /* if current is main-core, register current device to mpp service */
1109
+ if (mpp == enc->ccu->main_core)
1110
+ mpp_dev_register_srv(mpp, mpp->srv);
1111
+
1112
+ return 0;
1113
+}
1114
+
1115
+static int vepu_probe_default(struct platform_device *pdev)
1116
+{
1117
+ struct device *dev = &pdev->dev;
1118
+ struct vepu_dev *enc = NULL;
1119
+ struct mpp_dev *mpp = NULL;
1120
+ const struct of_device_id *match = NULL;
1121
+ int ret = 0;
1122
+
1123
+ enc = devm_kzalloc(dev, sizeof(struct vepu_dev), GFP_KERNEL);
1124
+ if (!enc)
1125
+ return -ENOMEM;
1126
+
1127
+ mpp = &enc->mpp;
1128
+ platform_set_drvdata(pdev, mpp);
1129
+
1130
+ if (pdev->dev.of_node) {
1131
+ match = of_match_node(mpp_vepu2_dt_match, pdev->dev.of_node);
1132
+ if (match)
1133
+ mpp->var = (struct mpp_dev_var *)match->data;
1134
+
1135
+ mpp->core_id = of_alias_get_id(pdev->dev.of_node, "vepu");
8401136 }
8411137
8421138 ret = mpp_dev_probe(mpp, pdev);
....@@ -859,39 +1155,72 @@
8591155 vepu_procfs_init(mpp);
8601156 /* register current device to mpp service */
8611157 mpp_dev_register_srv(mpp, mpp->srv);
862
- dev_info(dev, "probing finish\n");
8631158
8641159 return 0;
1160
+}
1161
+
1162
+static int vepu_probe(struct platform_device *pdev)
1163
+{
1164
+ int ret;
1165
+ struct device *dev = &pdev->dev;
1166
+ struct device_node *np = dev->of_node;
1167
+
1168
+ dev_info(dev, "probing start\n");
1169
+
1170
+ if (strstr(np->name, "ccu"))
1171
+ ret = vepu_ccu_probe(pdev);
1172
+ else if (strstr(np->name, "core"))
1173
+ ret = vepu_core_probe(pdev);
1174
+ else
1175
+ ret = vepu_probe_default(pdev);
1176
+
1177
+ dev_info(dev, "probing finish\n");
1178
+
1179
+ return ret;
8651180 }
8661181
8671182 static int vepu_remove(struct platform_device *pdev)
8681183 {
8691184 struct device *dev = &pdev->dev;
870
- struct vepu_dev *enc = platform_get_drvdata(pdev);
1185
+ struct device_node *np = dev->of_node;
8711186
872
- dev_info(dev, "remove device\n");
873
- mpp_dev_remove(&enc->mpp);
874
- vepu_procfs_remove(&enc->mpp);
1187
+ if (strstr(np->name, "ccu")) {
1188
+ dev_info(dev, "remove ccu device\n");
1189
+ } else if (strstr(np->name, "core")) {
1190
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
1191
+ struct vepu_dev *enc = to_vepu_dev(mpp);
1192
+
1193
+ dev_info(dev, "remove core\n");
1194
+ if (enc->ccu) {
1195
+ s32 core_id = mpp->core_id;
1196
+ struct vepu_ccu *ccu = enc->ccu;
1197
+ unsigned long flags;
1198
+
1199
+ spin_lock_irqsave(&ccu->lock, flags);
1200
+ ccu->core_num--;
1201
+ ccu->cores[core_id] = NULL;
1202
+ clear_bit(core_id, &ccu->core_idle);
1203
+ spin_unlock_irqrestore(&ccu->lock, flags);
1204
+ }
1205
+ mpp_dev_remove(&enc->mpp);
1206
+ vepu_procfs_remove(&enc->mpp);
1207
+ } else {
1208
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
1209
+
1210
+ dev_info(dev, "remove device\n");
1211
+ mpp_dev_remove(mpp);
1212
+ vepu_procfs_remove(mpp);
1213
+ }
8751214
8761215 return 0;
8771216 }
8781217
8791218 static void vepu_shutdown(struct platform_device *pdev)
8801219 {
881
- int ret;
882
- int val;
8831220 struct device *dev = &pdev->dev;
884
- struct vepu_dev *enc = platform_get_drvdata(pdev);
885
- struct mpp_dev *mpp = &enc->mpp;
8861221
887
- dev_info(dev, "shutdown device\n");
888
-
889
- atomic_inc(&mpp->srv->shutdown_request);
890
- ret = readx_poll_timeout(atomic_read,
891
- &mpp->task_count,
892
- val, val == 0, 20000, 200000);
893
- if (ret == -ETIMEDOUT)
894
- dev_err(dev, "wait total running time out\n");
1222
+ if (!strstr(dev_name(dev), "ccu"))
1223
+ mpp_dev_shutdown(pdev);
8951224 }
8961225
8971226 struct platform_driver rockchip_vepu2_driver = {