hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
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,12 +312,54 @@
281312 return NULL;
282313 }
283314
315
+static void *vepu_prepare(struct mpp_dev *mpp, struct mpp_task *mpp_task)
316
+{
317
+ struct vepu_dev *enc = to_vepu_dev(mpp);
318
+ struct vepu_ccu *ccu = enc->ccu;
319
+ unsigned long core_idle;
320
+ unsigned long flags;
321
+ s32 core_id;
322
+ u32 i;
323
+
324
+ spin_lock_irqsave(&ccu->lock, flags);
325
+
326
+ core_idle = ccu->core_idle;
327
+
328
+ for (i = 0; i < ccu->core_num; i++) {
329
+ struct mpp_dev *mpp = ccu->cores[i];
330
+
331
+ if (mpp && mpp->disable)
332
+ clear_bit(mpp->core_id, &core_idle);
333
+ }
334
+
335
+ core_id = find_first_bit(&core_idle, ccu->core_num);
336
+ if (core_id >= ARRAY_SIZE(ccu->cores)) {
337
+ mpp_task = NULL;
338
+ mpp_dbg_core("core %d all busy %lx\n", core_id, ccu->core_idle);
339
+ goto done;
340
+ }
341
+
342
+ core_id = array_index_nospec(core_id, MPP_MAX_CORE_NUM);
343
+ clear_bit(core_id, &ccu->core_idle);
344
+ mpp_task->mpp = ccu->cores[core_id];
345
+ mpp_task->core_id = core_id;
346
+
347
+ mpp_dbg_core("core cnt %d core %d set idle %lx -> %lx\n",
348
+ ccu->core_num, core_id, core_idle, ccu->core_idle);
349
+
350
+done:
351
+ spin_unlock_irqrestore(&ccu->lock, flags);
352
+
353
+ return mpp_task;
354
+}
355
+
284356 static int vepu_run(struct mpp_dev *mpp,
285357 struct mpp_task *mpp_task)
286358 {
287359 u32 i;
288360 u32 reg_en;
289361 struct vepu_task *task = to_vepu_task(mpp_task);
362
+ u32 timing_en = mpp->srv->timing_en;
290363
291364 mpp_debug_enter();
292365
....@@ -305,16 +378,32 @@
305378
306379 mpp_write_req(mpp, task->reg, s, e, reg_en);
307380 }
381
+
382
+ /* flush tlb before starting hardware */
383
+ mpp_iommu_flush_tlb(mpp->iommu_info);
384
+
308385 /* init current task */
309386 mpp->cur_task = mpp_task;
387
+
388
+ mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
389
+
310390 /* Last, flush the registers */
311391 wmb();
312392 mpp_write(mpp, VEPU2_REG_ENC_EN,
313393 task->reg[reg_en] | VEPU2_ENC_START);
314394
395
+ mpp_task_run_end(mpp_task, timing_en);
396
+
315397 mpp_debug_leave();
316398
317399 return 0;
400
+}
401
+
402
+static int vepu_px30_run(struct mpp_dev *mpp,
403
+ struct mpp_task *mpp_task)
404
+{
405
+ mpp_iommu_flush_tlb(mpp->iommu_info);
406
+ return vepu_run(mpp, mpp_task);
318407 }
319408
320409 static int vepu_irq(struct mpp_dev *mpp)
....@@ -333,6 +422,9 @@
333422 u32 err_mask;
334423 struct vepu_task *task = NULL;
335424 struct mpp_task *mpp_task = mpp->cur_task;
425
+ unsigned long core_idle;
426
+ struct vepu_dev *enc = to_vepu_dev(mpp);
427
+ struct vepu_ccu *ccu = enc->ccu;
336428
337429 /* FIXME use a spin lock here */
338430 if (!mpp_task) {
....@@ -354,6 +446,14 @@
354446 atomic_inc(&mpp->reset_request);
355447
356448 mpp_task_finish(mpp_task->session, mpp_task);
449
+ /* the whole vepu has no ccu that manage multi core */
450
+ if (ccu) {
451
+ core_idle = ccu->core_idle;
452
+ set_bit(mpp->core_id, &ccu->core_idle);
453
+
454
+ mpp_dbg_core("core %d isr idle %lx -> %lx\n", mpp->core_id, core_idle,
455
+ ccu->core_idle);
456
+ }
357457
358458 mpp_debug_leave();
359459
....@@ -380,6 +480,11 @@
380480 /* revert hack for irq status */
381481 task->reg[VEPU2_REG_INT_INDEX] = task->irq_status;
382482
483
+ if (task->bs_buf)
484
+ mpp_dma_buf_sync(task->bs_buf, 0,
485
+ task->reg[VEPU2_REG_STRM_INDEX] / 8 +
486
+ task->offset_bs,
487
+ DMA_FROM_DEVICE, true);
383488 mpp_debug_leave();
384489
385490 return 0;
....@@ -522,7 +627,7 @@
522627 }
523628 seq_puts(seq, "\n");
524629 /* item data*/
525
- seq_printf(seq, "|%8p|", session);
630
+ seq_printf(seq, "|%8d|", session->index);
526631 seq_printf(seq, "%8s|", mpp_device_name[session->device_type]);
527632 for (i = ENC_INFO_BASE; i < ENC_INFO_BUTT; i++) {
528633 u32 flag = priv->codec_info[i].flag;
....@@ -555,8 +660,9 @@
555660 mutex_lock(&mpp->srv->session_lock);
556661 list_for_each_entry_safe(session, n,
557662 &mpp->srv->session_list,
558
- session_link) {
559
- if (session->device_type != MPP_DEVICE_VEPU2)
663
+ service_link) {
664
+ if (session->device_type != MPP_DEVICE_VEPU2 &&
665
+ session->device_type != MPP_DEVICE_VEPU2_JPEG)
560666 continue;
561667 if (!session->priv)
562668 continue;
....@@ -571,13 +677,28 @@
571677 static int vepu_procfs_init(struct mpp_dev *mpp)
572678 {
573679 struct vepu_dev *enc = to_vepu_dev(mpp);
680
+ char name[32];
574681
575
- enc->procfs = proc_mkdir(mpp->dev->of_node->name, mpp->srv->procfs);
682
+ if (!mpp->dev || !mpp->dev->of_node || !mpp->dev->of_node->name ||
683
+ !mpp->srv || !mpp->srv->procfs)
684
+ return -EINVAL;
685
+ if (enc->ccu)
686
+ snprintf(name, sizeof(name) - 1, "%s%d",
687
+ mpp->dev->of_node->name, mpp->core_id);
688
+ else
689
+ snprintf(name, sizeof(name) - 1, "%s",
690
+ mpp->dev->of_node->name);
691
+
692
+ enc->procfs = proc_mkdir(name, mpp->srv->procfs);
576693 if (IS_ERR_OR_NULL(enc->procfs)) {
577694 mpp_err("failed on open procfs\n");
578695 enc->procfs = NULL;
579696 return -EIO;
580697 }
698
+
699
+ /* for common mpp_dev options */
700
+ mpp_procfs_create_common(enc->procfs, mpp);
701
+
581702 mpp_procfs_create_u32("aclk", 0644,
582703 enc->procfs, &enc->aclk_info.debug_rate_hz);
583704 mpp_procfs_create_u32("session_buffers", 0644,
....@@ -588,6 +709,17 @@
588709
589710 return 0;
590711 }
712
+
713
+static int vepu_procfs_ccu_init(struct mpp_dev *mpp)
714
+{
715
+ struct vepu_dev *enc = to_vepu_dev(mpp);
716
+
717
+ if (!enc->procfs)
718
+ goto done;
719
+
720
+done:
721
+ return 0;
722
+}
591723 #else
592724 static inline int vepu_procfs_remove(struct mpp_dev *mpp)
593725 {
....@@ -595,6 +727,11 @@
595727 }
596728
597729 static inline int vepu_procfs_init(struct mpp_dev *mpp)
730
+{
731
+ return 0;
732
+}
733
+
734
+static inline int vepu_procfs_ccu_init(struct mpp_dev *mpp)
598735 {
599736 return 0;
600737 }
....@@ -721,18 +858,26 @@
721858 static int vepu_reset(struct mpp_dev *mpp)
722859 {
723860 struct vepu_dev *enc = to_vepu_dev(mpp);
861
+ struct vepu_ccu *ccu = enc->ccu;
724862
863
+ mpp_write(mpp, VEPU2_REG_ENC_EN, 0);
864
+ udelay(5);
725865 if (enc->rst_a && enc->rst_h) {
726866 /* Don't skip this or iommu won't work after reset */
727
- rockchip_pmu_idle_request(mpp->dev, true);
867
+ mpp_pmu_idle_request(mpp, true);
728868 mpp_safe_reset(enc->rst_a);
729869 mpp_safe_reset(enc->rst_h);
730870 udelay(5);
731871 mpp_safe_unreset(enc->rst_a);
732872 mpp_safe_unreset(enc->rst_h);
733
- rockchip_pmu_idle_request(mpp->dev, false);
873
+ mpp_pmu_idle_request(mpp, false);
734874 }
735875 mpp_write(mpp, VEPU2_REG_INT, VEPU2_INT_CLEAR);
876
+
877
+ if (ccu) {
878
+ set_bit(mpp->core_id, &ccu->core_idle);
879
+ mpp_dbg_core("core %d reset idle %lx\n", mpp->core_id, ccu->core_idle);
880
+ }
736881
737882 return 0;
738883 }
....@@ -771,6 +916,36 @@
771916 .dump_session = vepu_dump_session,
772917 };
773918
919
+static struct mpp_dev_ops vepu_px30_dev_ops = {
920
+ .alloc_task = vepu_alloc_task,
921
+ .run = vepu_px30_run,
922
+ .irq = vepu_irq,
923
+ .isr = vepu_isr,
924
+ .finish = vepu_finish,
925
+ .result = vepu_result,
926
+ .free_task = vepu_free_task,
927
+ .ioctl = vepu_control,
928
+ .init_session = vepu_init_session,
929
+ .free_session = vepu_free_session,
930
+ .dump_session = vepu_dump_session,
931
+};
932
+
933
+static struct mpp_dev_ops vepu_ccu_dev_ops = {
934
+ .alloc_task = vepu_alloc_task,
935
+ .prepare = vepu_prepare,
936
+ .run = vepu_run,
937
+ .irq = vepu_irq,
938
+ .isr = vepu_isr,
939
+ .finish = vepu_finish,
940
+ .result = vepu_result,
941
+ .free_task = vepu_free_task,
942
+ .ioctl = vepu_control,
943
+ .init_session = vepu_init_session,
944
+ .free_session = vepu_free_session,
945
+ .dump_session = vepu_dump_session,
946
+};
947
+
948
+
774949 static const struct mpp_dev_var vepu_v2_data = {
775950 .device_type = MPP_DEVICE_VEPU2,
776951 .hw_info = &vepu_v2_hw_info,
....@@ -784,7 +959,15 @@
784959 .hw_info = &vepu_v2_hw_info,
785960 .trans_info = trans_rk_vepu2,
786961 .hw_ops = &vepu_px30_hw_ops,
787
- .dev_ops = &vepu_v2_dev_ops,
962
+ .dev_ops = &vepu_px30_dev_ops,
963
+};
964
+
965
+static const struct mpp_dev_var vepu_ccu_data = {
966
+ .device_type = MPP_DEVICE_VEPU2_JPEG,
967
+ .hw_info = &vepu_v2_hw_info,
968
+ .trans_info = trans_rk_vepu2,
969
+ .hw_ops = &vepu_v2_hw_ops,
970
+ .dev_ops = &vepu_ccu_dev_ops,
788971 };
789972
790973 static const struct of_device_id mpp_vepu2_dt_match[] = {
....@@ -798,10 +981,83 @@
798981 .data = &vepu_px30_data,
799982 },
800983 #endif
984
+#ifdef CONFIG_CPU_RK3588
985
+ {
986
+ .compatible = "rockchip,vpu-jpege-core",
987
+ .data = &vepu_ccu_data,
988
+ },
989
+ {
990
+ .compatible = "rockchip,vpu-jpege-ccu",
991
+ },
992
+#endif
801993 {},
802994 };
803995
804
-static int vepu_probe(struct platform_device *pdev)
996
+static int vepu_ccu_probe(struct platform_device *pdev)
997
+{
998
+ struct vepu_ccu *ccu;
999
+ struct device *dev = &pdev->dev;
1000
+
1001
+ ccu = devm_kzalloc(dev, sizeof(*ccu), GFP_KERNEL);
1002
+ if (!ccu)
1003
+ return -ENOMEM;
1004
+
1005
+ platform_set_drvdata(pdev, ccu);
1006
+ spin_lock_init(&ccu->lock);
1007
+ return 0;
1008
+}
1009
+
1010
+static int vepu_attach_ccu(struct device *dev, struct vepu_dev *enc)
1011
+{
1012
+ struct device_node *np;
1013
+ struct platform_device *pdev;
1014
+ struct vepu_ccu *ccu;
1015
+ unsigned long flags;
1016
+
1017
+ np = of_parse_phandle(dev->of_node, "rockchip,ccu", 0);
1018
+ if (!np || !of_device_is_available(np))
1019
+ return -ENODEV;
1020
+
1021
+ pdev = of_find_device_by_node(np);
1022
+ of_node_put(np);
1023
+ if (!pdev)
1024
+ return -ENODEV;
1025
+
1026
+ ccu = platform_get_drvdata(pdev);
1027
+ if (!ccu)
1028
+ return -ENOMEM;
1029
+
1030
+ spin_lock_irqsave(&ccu->lock, flags);
1031
+ ccu->core_num++;
1032
+ ccu->cores[enc->mpp.core_id] = &enc->mpp;
1033
+ set_bit(enc->mpp.core_id, &ccu->core_idle);
1034
+ spin_unlock_irqrestore(&ccu->lock, flags);
1035
+
1036
+ /* attach the ccu-domain to current core */
1037
+ if (!ccu->main_core) {
1038
+ /**
1039
+ * set the first device for the main-core,
1040
+ * then the domain of the main-core named ccu-domain
1041
+ */
1042
+ ccu->main_core = &enc->mpp;
1043
+ } else {
1044
+ struct mpp_iommu_info *ccu_info, *cur_info;
1045
+
1046
+ /* set the ccu domain for current device */
1047
+ ccu_info = ccu->main_core->iommu_info;
1048
+ cur_info = enc->mpp.iommu_info;
1049
+
1050
+ if (cur_info)
1051
+ cur_info->domain = ccu_info->domain;
1052
+ mpp_iommu_attach(cur_info);
1053
+ }
1054
+ enc->ccu = ccu;
1055
+
1056
+ dev_info(dev, "attach ccu success\n");
1057
+ return 0;
1058
+}
1059
+
1060
+static int vepu_core_probe(struct platform_device *pdev)
8051061 {
8061062 struct device *dev = &pdev->dev;
8071063 struct vepu_dev *enc = NULL;
....@@ -809,18 +1065,72 @@
8091065 const struct of_device_id *match = NULL;
8101066 int ret = 0;
8111067
812
- dev_info(dev, "probe device\n");
8131068 enc = devm_kzalloc(dev, sizeof(struct vepu_dev), GFP_KERNEL);
8141069 if (!enc)
8151070 return -ENOMEM;
8161071
8171072 mpp = &enc->mpp;
818
- platform_set_drvdata(pdev, enc);
1073
+ platform_set_drvdata(pdev, mpp);
8191074
8201075 if (pdev->dev.of_node) {
8211076 match = of_match_node(mpp_vepu2_dt_match, pdev->dev.of_node);
8221077 if (match)
8231078 mpp->var = (struct mpp_dev_var *)match->data;
1079
+
1080
+ mpp->core_id = of_alias_get_id(pdev->dev.of_node, "jpege");
1081
+ }
1082
+
1083
+ ret = mpp_dev_probe(mpp, pdev);
1084
+ if (ret) {
1085
+ dev_err(dev, "probe sub driver failed\n");
1086
+ return -EINVAL;
1087
+ }
1088
+ /* current device attach to ccu */
1089
+ ret = vepu_attach_ccu(dev, enc);
1090
+ if (ret)
1091
+ return ret;
1092
+
1093
+ ret = devm_request_threaded_irq(dev, mpp->irq,
1094
+ mpp_dev_irq,
1095
+ mpp_dev_isr_sched,
1096
+ IRQF_SHARED,
1097
+ dev_name(dev), mpp);
1098
+ if (ret) {
1099
+ dev_err(dev, "register interrupter runtime failed\n");
1100
+ return -EINVAL;
1101
+ }
1102
+
1103
+ mpp->session_max_buffers = VEPU2_SESSION_MAX_BUFFERS;
1104
+ vepu_procfs_init(mpp);
1105
+ vepu_procfs_ccu_init(mpp);
1106
+ /* if current is main-core, register current device to mpp service */
1107
+ if (mpp == enc->ccu->main_core)
1108
+ mpp_dev_register_srv(mpp, mpp->srv);
1109
+
1110
+ return 0;
1111
+}
1112
+
1113
+static int vepu_probe_default(struct platform_device *pdev)
1114
+{
1115
+ struct device *dev = &pdev->dev;
1116
+ struct vepu_dev *enc = NULL;
1117
+ struct mpp_dev *mpp = NULL;
1118
+ const struct of_device_id *match = NULL;
1119
+ int ret = 0;
1120
+
1121
+ enc = devm_kzalloc(dev, sizeof(struct vepu_dev), GFP_KERNEL);
1122
+ if (!enc)
1123
+ return -ENOMEM;
1124
+
1125
+ mpp = &enc->mpp;
1126
+ platform_set_drvdata(pdev, mpp);
1127
+
1128
+ if (pdev->dev.of_node) {
1129
+ match = of_match_node(mpp_vepu2_dt_match, pdev->dev.of_node);
1130
+ if (match)
1131
+ mpp->var = (struct mpp_dev_var *)match->data;
1132
+
1133
+ mpp->core_id = of_alias_get_id(pdev->dev.of_node, "vepu");
8241134 }
8251135
8261136 ret = mpp_dev_probe(mpp, pdev);
....@@ -843,39 +1153,72 @@
8431153 vepu_procfs_init(mpp);
8441154 /* register current device to mpp service */
8451155 mpp_dev_register_srv(mpp, mpp->srv);
846
- dev_info(dev, "probing finish\n");
8471156
8481157 return 0;
1158
+}
1159
+
1160
+static int vepu_probe(struct platform_device *pdev)
1161
+{
1162
+ int ret;
1163
+ struct device *dev = &pdev->dev;
1164
+ struct device_node *np = dev->of_node;
1165
+
1166
+ dev_info(dev, "probing start\n");
1167
+
1168
+ if (strstr(np->name, "ccu"))
1169
+ ret = vepu_ccu_probe(pdev);
1170
+ else if (strstr(np->name, "core"))
1171
+ ret = vepu_core_probe(pdev);
1172
+ else
1173
+ ret = vepu_probe_default(pdev);
1174
+
1175
+ dev_info(dev, "probing finish\n");
1176
+
1177
+ return ret;
8491178 }
8501179
8511180 static int vepu_remove(struct platform_device *pdev)
8521181 {
8531182 struct device *dev = &pdev->dev;
854
- struct vepu_dev *enc = platform_get_drvdata(pdev);
1183
+ struct device_node *np = dev->of_node;
8551184
856
- dev_info(dev, "remove device\n");
857
- mpp_dev_remove(&enc->mpp);
858
- vepu_procfs_remove(&enc->mpp);
1185
+ if (strstr(np->name, "ccu")) {
1186
+ dev_info(dev, "remove ccu device\n");
1187
+ } else if (strstr(np->name, "core")) {
1188
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
1189
+ struct vepu_dev *enc = to_vepu_dev(mpp);
1190
+
1191
+ dev_info(dev, "remove core\n");
1192
+ if (enc->ccu) {
1193
+ s32 core_id = mpp->core_id;
1194
+ struct vepu_ccu *ccu = enc->ccu;
1195
+ unsigned long flags;
1196
+
1197
+ spin_lock_irqsave(&ccu->lock, flags);
1198
+ ccu->core_num--;
1199
+ ccu->cores[core_id] = NULL;
1200
+ clear_bit(core_id, &ccu->core_idle);
1201
+ spin_unlock_irqrestore(&ccu->lock, flags);
1202
+ }
1203
+ mpp_dev_remove(&enc->mpp);
1204
+ vepu_procfs_remove(&enc->mpp);
1205
+ } else {
1206
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
1207
+
1208
+ dev_info(dev, "remove device\n");
1209
+ mpp_dev_remove(mpp);
1210
+ vepu_procfs_remove(mpp);
1211
+ }
8591212
8601213 return 0;
8611214 }
8621215
8631216 static void vepu_shutdown(struct platform_device *pdev)
8641217 {
865
- int ret;
866
- int val;
8671218 struct device *dev = &pdev->dev;
868
- struct vepu_dev *enc = platform_get_drvdata(pdev);
869
- struct mpp_dev *mpp = &enc->mpp;
8701219
871
- dev_info(dev, "shutdown device\n");
872
-
873
- atomic_inc(&mpp->srv->shutdown_request);
874
- ret = readx_poll_timeout(atomic_read,
875
- &mpp->task_count,
876
- val, val == 0, 20000, 200000);
877
- if (ret == -ETIMEDOUT)
878
- dev_err(dev, "wait total running time out\n");
1220
+ if (!strstr(dev_name(dev), "ccu"))
1221
+ mpp_dev_shutdown(pdev);
8791222 }
8801223
8811224 struct platform_driver rockchip_vepu2_driver = {