hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/video/rockchip/mpp/mpp_rkvdec2.c
....@@ -7,6 +7,8 @@
77 * Ding Wei, leo.ding@rock-chips.com
88 *
99 */
10
+#include <linux/pm_runtime.h>
11
+
1012 #include "mpp_debug.h"
1113 #include "mpp_common.h"
1214 #include "mpp_iommu.h"
....@@ -23,7 +25,7 @@
2325 #include <soc/rockchip/rockchip_iommu.h>
2426
2527 #ifdef CONFIG_PM_DEVFREQ
26
-#include "../../../devfreq/governor.h"
28
+#include "../drivers/devfreq/governor.h"
2729 #endif
2830
2931 /*
....@@ -38,13 +40,22 @@
3840 .link_info = &rkvdec_link_v2_hw_info,
3941 };
4042
41
-static struct mpp_hw_info rkvdec_rk3568_hw_info = {
43
+static struct mpp_hw_info rkvdec_rk356x_hw_info = {
4244 .reg_num = RKVDEC_REG_NUM,
4345 .reg_id = RKVDEC_REG_HW_ID_INDEX,
4446 .reg_start = RKVDEC_REG_START_INDEX,
4547 .reg_end = RKVDEC_REG_END_INDEX,
4648 .reg_en = RKVDEC_REG_START_EN_INDEX,
47
- .link_info = &rkvdec_link_rk3568_hw_info,
49
+ .link_info = &rkvdec_link_rk356x_hw_info,
50
+};
51
+
52
+static struct mpp_hw_info rkvdec_vdpu382_hw_info = {
53
+ .reg_num = RKVDEC_REG_NUM,
54
+ .reg_id = RKVDEC_REG_HW_ID_INDEX,
55
+ .reg_start = RKVDEC_REG_START_INDEX,
56
+ .reg_end = RKVDEC_REG_END_INDEX,
57
+ .reg_en = RKVDEC_REG_START_EN_INDEX,
58
+ .link_info = &rkvdec_link_vdpu382_hw_info,
4859 };
4960
5061 /*
....@@ -182,9 +193,8 @@
182193 return 0;
183194 }
184195
185
-static int mpp_set_rcbbuf(struct mpp_dev *mpp,
186
- struct mpp_session *session,
187
- struct rkvdec2_task *task)
196
+int mpp_set_rcbbuf(struct mpp_dev *mpp, struct mpp_session *session,
197
+ struct mpp_task *task)
188198 {
189199 struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
190200 struct rkvdec2_session_priv *priv = session->priv;
....@@ -204,10 +214,11 @@
204214 for (i = 0; i < rcb_inf->cnt; i++) {
205215 reg_idx = rcb_inf->elem[i].index;
206216 rcb_size = rcb_inf->elem[i].size;
207
- if (!rcb_size ||
208
- rcb_offset > dec->sram_size ||
209
- (rcb_offset + rcb_size) > dec->rcb_size)
217
+ if ((rcb_offset + rcb_size) > dec->rcb_size) {
218
+ mpp_debug(DEBUG_SRAM_INFO,
219
+ "rcb: reg %d use original buffer\n", reg_idx);
210220 continue;
221
+ }
211222 mpp_debug(DEBUG_SRAM_INFO, "rcb: reg %d offset %d, size %d\n",
212223 reg_idx, rcb_offset, rcb_size);
213224 task->reg[reg_idx] = dec->rcb_iova + rcb_offset;
....@@ -220,45 +231,38 @@
220231 return 0;
221232 }
222233
223
-void *rkvdec2_alloc_task(struct mpp_session *session,
224
- struct mpp_task_msgs *msgs)
234
+int rkvdec2_task_init(struct mpp_dev *mpp, struct mpp_session *session,
235
+ struct rkvdec2_task *task, struct mpp_task_msgs *msgs)
225236 {
226237 int ret;
227
- struct mpp_task *mpp_task = NULL;
228
- struct rkvdec2_task *task = NULL;
229
- struct mpp_dev *mpp = session->mpp;
238
+ struct mpp_task *mpp_task = &task->mpp_task;
230239
231240 mpp_debug_enter();
232241
233
- task = kzalloc(sizeof(*task), GFP_KERNEL);
234
- if (!task)
235
- return NULL;
236
-
237
- mpp_task = &task->mpp_task;
238242 mpp_task_init(session, mpp_task);
239243 mpp_task->hw_info = mpp->var->hw_info;
240244 mpp_task->reg = task->reg;
241245 /* extract reqs for current task */
242246 ret = rkvdec2_extract_task_msg(session, task, msgs);
243247 if (ret)
244
- goto fail;
248
+ return ret;
245249
246250 /* process fd in register */
247251 if (!(msgs->flags & MPP_FLAGS_REG_FD_NO_TRANS)) {
248252 u32 fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_FORMAT_INDEX]);
249253
250
- ret = mpp_translate_reg_address(session, &task->mpp_task,
254
+ ret = mpp_translate_reg_address(session, mpp_task,
251255 fmt, task->reg, &task->off_inf);
252256 if (ret)
253257 goto fail;
254258
255
- mpp_translate_reg_offset_info(&task->mpp_task, &task->off_inf, task->reg);
259
+ mpp_translate_reg_offset_info(mpp_task, &task->off_inf, task->reg);
256260 }
257
- mpp_set_rcbbuf(mpp, session, task);
261
+
258262 task->strm_addr = task->reg[RKVDEC_REG_RLC_BASE_INDEX];
259263 task->clk_mode = CLK_MODE_NORMAL;
260264 task->slot_idx = -1;
261
- init_waitqueue_head(&task->wait);
265
+ init_waitqueue_head(&mpp_task->wait);
262266 /* get resolution info */
263267 if (session->priv) {
264268 struct rkvdec2_session_priv *priv = session->priv;
....@@ -274,18 +278,37 @@
274278
275279 mpp_debug_leave();
276280
277
- return mpp_task;
281
+ return 0;
278282
279283 fail:
280284 mpp_task_dump_mem_region(mpp, mpp_task);
281285 mpp_task_dump_reg(mpp, mpp_task);
282286 mpp_task_finalize(session, mpp_task);
283
- kfree(task);
284
- return NULL;
287
+ return ret;
288
+}
289
+
290
+void *rkvdec2_alloc_task(struct mpp_session *session,
291
+ struct mpp_task_msgs *msgs)
292
+{
293
+ int ret;
294
+ struct rkvdec2_task *task;
295
+
296
+ task = kzalloc(sizeof(*task), GFP_KERNEL);
297
+ if (!task)
298
+ return NULL;
299
+
300
+ ret = rkvdec2_task_init(session->mpp, session, task, msgs);
301
+ if (ret) {
302
+ kfree(task);
303
+ return NULL;
304
+ }
305
+ mpp_set_rcbbuf(session->mpp, session, &task->mpp_task);
306
+
307
+ return &task->mpp_task;
285308 }
286309
287310 static void *rkvdec2_rk3568_alloc_task(struct mpp_session *session,
288
- struct mpp_task_msgs *msgs)
311
+ struct mpp_task_msgs *msgs)
289312 {
290313 u32 fmt;
291314 struct mpp_task *mpp_task = NULL;
....@@ -400,7 +423,7 @@
400423 return IRQ_HANDLED;
401424 }
402425 mpp_task->hw_cycles = mpp_read(mpp, RKVDEC_PERF_WORKING_CNT);
403
- mpp_time_diff_with_hw_time(mpp_task, dec->core_clk_info.real_rate_hz);
426
+ mpp_time_diff_with_hw_time(mpp_task, dec->cycle_clk->real_rate_hz);
404427 mpp->cur_task = NULL;
405428 task = to_rkvdec2_task(mpp_task);
406429 task->irq_status = mpp->irq_status;
....@@ -410,9 +433,10 @@
410433 RKVDEC_TIMEOUT_STA | RKVDEC_ERROR_STA;
411434 if (err_mask & task->irq_status) {
412435 atomic_inc(&mpp->reset_request);
413
- mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n",
414
- task->irq_status);
415
- mpp_task_dump_hw_reg(mpp, mpp_task);
436
+ if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG)) {
437
+ mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n", task->irq_status);
438
+ mpp_task_dump_hw_reg(mpp);
439
+ }
416440 }
417441
418442 mpp_task_finish(mpp_task->session, mpp_task);
....@@ -483,6 +507,18 @@
483507 dec_length = dec_get - task->strm_addr;
484508 task->reg[RKVDEC_REG_RLC_BASE_INDEX] = dec_length << 10;
485509 mpp_debug(DEBUG_REGISTER, "dec_get %08x dec_length %d\n", dec_get, dec_length);
510
+
511
+ if (mpp->srv->timing_en) {
512
+ s64 time_diff;
513
+
514
+ mpp_task->on_finish = ktime_get();
515
+ set_bit(TASK_TIMING_FINISH, &mpp_task->state);
516
+
517
+ time_diff = ktime_us_delta(mpp_task->on_finish, mpp_task->on_create);
518
+
519
+ if (mpp->timing_check && time_diff > (s64)mpp->timing_check)
520
+ mpp_task_dump_timing(mpp_task, time_diff);
521
+ }
486522
487523 mpp_debug_leave();
488524
....@@ -565,16 +601,6 @@
565601 }
566602 }
567603 } break;
568
- case MPP_CMD_SET_ERR_REF_HACK: {
569
- struct rkvdec2_dev *dec = to_rkvdec2_dev(session->mpp);
570
- u32 err_ref_hack_en = 0;
571
-
572
- if (copy_from_user(&err_ref_hack_en, req->data, sizeof(u32))) {
573
- mpp_err("copy_from_user failed\n");
574
- return -EINVAL;
575
- }
576
- dec->err_ref_hack = err_ref_hack_en;
577
- } break;
578604 default: {
579605 mpp_err("unknown mpp ioctl cmd %x\n", req->cmd);
580606 } break;
....@@ -633,8 +659,15 @@
633659 static int rkvdec2_procfs_init(struct mpp_dev *mpp)
634660 {
635661 struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
662
+ char name[32];
636663
637
- dec->procfs = proc_mkdir(mpp->dev->of_node->name, mpp->srv->procfs);
664
+ if (!mpp->dev || !mpp->dev->of_node || !mpp->dev->of_node->name ||
665
+ !mpp->srv || !mpp->srv->procfs)
666
+ return -EINVAL;
667
+
668
+ snprintf(name, sizeof(name) - 1, "%s%d",
669
+ mpp->dev->of_node->name, mpp->core_id);
670
+ dec->procfs = proc_mkdir(name, mpp->srv->procfs);
638671 if (IS_ERR_OR_NULL(dec->procfs)) {
639672 mpp_err("failed on open procfs\n");
640673 dec->procfs = NULL;
....@@ -797,7 +830,7 @@
797830 };
798831
799832 static struct monitor_dev_profile vdec2_mdevp = {
800
- .type = MONITOR_TPYE_DEV,
833
+ .type = MONITOR_TYPE_DEV,
801834 .low_temp_adjust = rockchip_monitor_dev_low_temp_adjust,
802835 .high_temp_adjust = rockchip_monitor_dev_high_temp_adjust,
803836 };
....@@ -905,6 +938,42 @@
905938
906939 return 0;
907940 }
941
+
942
+void mpp_devfreq_set_core_rate(struct mpp_dev *mpp, enum MPP_CLOCK_MODE mode)
943
+{
944
+ struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
945
+
946
+ if (dec->devfreq) {
947
+ unsigned long core_rate_hz;
948
+
949
+ mutex_lock(&dec->devfreq->lock);
950
+ core_rate_hz = mpp_get_clk_info_rate_hz(&dec->core_clk_info, mode);
951
+ if (dec->core_rate_hz != core_rate_hz) {
952
+ dec->core_rate_hz = core_rate_hz;
953
+ update_devfreq(dec->devfreq);
954
+ }
955
+ mutex_unlock(&dec->devfreq->lock);
956
+ }
957
+
958
+ mpp_clk_set_rate(&dec->core_clk_info, mode);
959
+}
960
+#else
961
+static inline int rkvdec2_devfreq_init(struct mpp_dev *mpp)
962
+{
963
+ return 0;
964
+}
965
+
966
+static inline int rkvdec2_devfreq_remove(struct mpp_dev *mpp)
967
+{
968
+ return 0;
969
+}
970
+
971
+void mpp_devfreq_set_core_rate(struct mpp_dev *mpp, enum MPP_CLOCK_MODE mode)
972
+{
973
+ struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
974
+
975
+ mpp_clk_set_rate(&dec->core_clk_info, mode);
976
+}
908977 #endif
909978
910979 static int rkvdec2_init(struct mpp_dev *mpp)
....@@ -937,6 +1006,7 @@
9371006 mpp_set_clk_info_rate_hz(&dec->cabac_clk_info, CLK_MODE_DEFAULT, 200 * MHZ);
9381007 mpp_set_clk_info_rate_hz(&dec->hevc_cabac_clk_info, CLK_MODE_DEFAULT, 300 * MHZ);
9391008
1009
+ dec->cycle_clk = &dec->aclk_info;
9401010 /* Get normal max workload from dtsi */
9411011 of_property_read_u32(mpp->dev->of_node,
9421012 "rockchip,default-max-load", &dec->default_max_load);
....@@ -963,11 +1033,10 @@
9631033 if (!dec->rst_hevc_cabac)
9641034 mpp_err("No hevc cabac reset resource define\n");
9651035
966
-#ifdef CONFIG_PM_DEVFREQ
9671036 ret = rkvdec2_devfreq_init(mpp);
9681037 if (ret)
9691038 mpp_err("failed to add vdec devfreq\n");
970
-#endif
1039
+
9711040 return ret;
9721041 }
9731042
....@@ -992,9 +1061,7 @@
9921061 {
9931062 struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
9941063
995
-#ifdef CONFIG_PM_DEVFREQ
9961064 rkvdec2_devfreq_remove(mpp);
997
-#endif
9981065
9991066 if (dec->fix)
10001067 mpp_dma_free(dec->fix);
....@@ -1073,23 +1140,7 @@
10731140 mpp_clk_set_rate(&dec->aclk_info, task->clk_mode);
10741141 mpp_clk_set_rate(&dec->cabac_clk_info, task->clk_mode);
10751142 mpp_clk_set_rate(&dec->hevc_cabac_clk_info, task->clk_mode);
1076
-
1077
-#ifdef CONFIG_PM_DEVFREQ
1078
- if (dec->devfreq) {
1079
- unsigned long core_rate_hz;
1080
-
1081
- mutex_lock(&dec->devfreq->lock);
1082
- core_rate_hz = mpp_get_clk_info_rate_hz(&dec->core_clk_info, task->clk_mode);
1083
- if (dec->core_rate_hz != core_rate_hz) {
1084
- dec->core_rate_hz = core_rate_hz;
1085
- update_devfreq(dec->devfreq);
1086
- }
1087
- mutex_unlock(&dec->devfreq->lock);
1088
-
1089
- return 0;
1090
- }
1091
-#endif
1092
- mpp_clk_set_rate(&dec->core_clk_info, task->clk_mode);
1143
+ mpp_devfreq_set_core_rate(mpp, task->clk_mode);
10931144
10941145 return 0;
10951146 }
....@@ -1112,16 +1163,31 @@
11121163
11131164 }
11141165
1115
-static int rkvdec2_reset(struct mpp_dev *mpp)
1166
+static int rkvdec2_sip_reset(struct mpp_dev *mpp)
1167
+{
1168
+ mpp_debug_enter();
1169
+
1170
+ if (IS_REACHABLE(CONFIG_ROCKCHIP_SIP)) {
1171
+ /* sip reset */
1172
+ rockchip_dmcfreq_lock();
1173
+ sip_smc_vpu_reset(0, 0, 0);
1174
+ rockchip_dmcfreq_unlock();
1175
+ } else {
1176
+ rkvdec2_reset(mpp);
1177
+ }
1178
+
1179
+ mpp_debug_leave();
1180
+
1181
+ return 0;
1182
+}
1183
+
1184
+int rkvdec2_reset(struct mpp_dev *mpp)
11161185 {
11171186 struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
11181187 int ret = 0;
11191188
11201189 mpp_debug_enter();
1121
-#ifdef CONFIG_PM_DEVFREQ
1122
- if (dec->devfreq)
1123
- mutex_lock(&dec->devfreq->lock);
1124
-#endif
1190
+
11251191 /* safe reset first*/
11261192 ret = rkvdec2_soft_reset(mpp);
11271193
....@@ -1146,28 +1212,6 @@
11461212 mpp_safe_unreset(dec->rst_hevc_cabac);
11471213 mpp_pmu_idle_request(mpp, false);
11481214 }
1149
-#ifdef CONFIG_PM_DEVFREQ
1150
- if (dec->devfreq)
1151
- mutex_unlock(&dec->devfreq->lock);
1152
-#endif
1153
- mpp_debug_leave();
1154
-
1155
- return 0;
1156
-}
1157
-
1158
-static int rkvdec2_sip_reset(struct mpp_dev *mpp)
1159
-{
1160
- mpp_debug_enter();
1161
-
1162
- if (IS_REACHABLE(CONFIG_ROCKCHIP_SIP)) {
1163
- /* sip reset */
1164
- rockchip_dmcfreq_lock();
1165
- sip_smc_vpu_reset(0, 0, 0);
1166
- rockchip_dmcfreq_unlock();
1167
- } else {
1168
- rkvdec2_reset(mpp);
1169
- }
1170
-
11711215 mpp_debug_leave();
11721216
11731217 return 0;
....@@ -1185,6 +1229,15 @@
11851229 static struct mpp_hw_ops rkvdec_rk3568_hw_ops = {
11861230 .init = rkvdec2_rk3568_init,
11871231 .exit = rkvdec2_rk3568_exit,
1232
+ .clk_on = rkvdec2_clk_on,
1233
+ .clk_off = rkvdec2_clk_off,
1234
+ .get_freq = rkvdec2_get_freq,
1235
+ .set_freq = rkvdec2_set_freq,
1236
+ .reset = rkvdec2_sip_reset,
1237
+};
1238
+
1239
+static struct mpp_hw_ops rkvdec_rk3588_hw_ops = {
1240
+ .init = rkvdec2_init,
11881241 .clk_on = rkvdec2_clk_on,
11891242 .clk_off = rkvdec2_clk_off,
11901243 .get_freq = rkvdec2_get_freq,
....@@ -1229,10 +1282,26 @@
12291282
12301283 static const struct mpp_dev_var rkvdec_rk3568_data = {
12311284 .device_type = MPP_DEVICE_RKVDEC,
1232
- .hw_info = &rkvdec_rk3568_hw_info,
1285
+ .hw_info = &rkvdec_rk356x_hw_info,
12331286 .trans_info = rkvdec_v2_trans,
12341287 .hw_ops = &rkvdec_rk3568_hw_ops,
12351288 .dev_ops = &rkvdec_rk3568_dev_ops,
1289
+};
1290
+
1291
+static const struct mpp_dev_var rkvdec_vdpu382_data = {
1292
+ .device_type = MPP_DEVICE_RKVDEC,
1293
+ .hw_info = &rkvdec_vdpu382_hw_info,
1294
+ .trans_info = rkvdec_v2_trans,
1295
+ .hw_ops = &rkvdec_v2_hw_ops,
1296
+ .dev_ops = &rkvdec_v2_dev_ops,
1297
+};
1298
+
1299
+static const struct mpp_dev_var rkvdec_rk3588_data = {
1300
+ .device_type = MPP_DEVICE_RKVDEC,
1301
+ .hw_info = &rkvdec_v2_hw_info,
1302
+ .trans_info = rkvdec_v2_trans,
1303
+ .hw_ops = &rkvdec_rk3588_hw_ops,
1304
+ .dev_ops = &rkvdec_v2_dev_ops,
12361305 };
12371306
12381307 static const struct of_device_id mpp_rkvdec2_dt_match[] = {
....@@ -1246,8 +1315,91 @@
12461315 .data = &rkvdec_rk3568_data,
12471316 },
12481317 #endif
1318
+#ifdef CONFIG_CPU_RK3588
1319
+ {
1320
+ .compatible = "rockchip,rkv-decoder-v2-ccu",
1321
+ .data = &rkvdec_rk3588_data,
1322
+ },
1323
+#endif
1324
+#ifdef CONFIG_CPU_RK3528
1325
+ {
1326
+ .compatible = "rockchip,rkv-decoder-rk3528",
1327
+ .data = &rkvdec_vdpu382_data,
1328
+ },
1329
+#endif
1330
+#ifdef CONFIG_CPU_RK3562
1331
+ {
1332
+ .compatible = "rockchip,rkv-decoder-rk3562",
1333
+ .data = &rkvdec_vdpu382_data,
1334
+ },
1335
+#endif
12491336 {},
12501337 };
1338
+
1339
+static int rkvdec2_ccu_remove(struct device *dev)
1340
+{
1341
+ device_init_wakeup(dev, false);
1342
+ pm_runtime_disable(dev);
1343
+
1344
+ return 0;
1345
+}
1346
+
1347
+static int rkvdec2_ccu_probe(struct platform_device *pdev)
1348
+{
1349
+ struct rkvdec2_ccu *ccu;
1350
+ struct resource *res;
1351
+ struct device *dev = &pdev->dev;
1352
+ u32 ccu_mode;
1353
+
1354
+ ccu = devm_kzalloc(dev, sizeof(*ccu), GFP_KERNEL);
1355
+ if (!ccu)
1356
+ return -ENOMEM;
1357
+
1358
+ ccu->dev = dev;
1359
+ /* use task-level soft ccu default */
1360
+ ccu->ccu_mode = RKVDEC2_CCU_TASK_SOFT;
1361
+ atomic_set(&ccu->power_enabled, 0);
1362
+ INIT_LIST_HEAD(&ccu->unused_list);
1363
+ INIT_LIST_HEAD(&ccu->used_list);
1364
+ platform_set_drvdata(pdev, ccu);
1365
+
1366
+ if (!of_property_read_u32(dev->of_node, "rockchip,ccu-mode", &ccu_mode)) {
1367
+ if (ccu_mode <= RKVDEC2_CCU_MODE_NULL || ccu_mode >= RKVDEC2_CCU_MODE_BUTT)
1368
+ ccu_mode = RKVDEC2_CCU_TASK_SOFT;
1369
+ ccu->ccu_mode = (enum RKVDEC2_CCU_MODE)ccu_mode;
1370
+ }
1371
+
1372
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ccu");
1373
+ if (!res) {
1374
+ dev_err(dev, "no memory resource defined\n");
1375
+ return -ENODEV;
1376
+ }
1377
+
1378
+ ccu->reg_base = devm_ioremap(dev, res->start, resource_size(res));
1379
+ if (!ccu->reg_base) {
1380
+ dev_err(dev, "ioremap failed for resource %pR\n", res);
1381
+ return -ENODEV;
1382
+ }
1383
+
1384
+ ccu->aclk_info.clk = devm_clk_get(dev, "aclk_ccu");
1385
+ if (!ccu->aclk_info.clk)
1386
+ mpp_err("failed on clk_get ccu aclk\n");
1387
+
1388
+ ccu->rst_a = devm_reset_control_get(dev, "video_ccu");
1389
+ if (ccu->rst_a)
1390
+ mpp_safe_unreset(ccu->rst_a);
1391
+ else
1392
+ mpp_err("failed on clk_get ccu reset\n");
1393
+
1394
+ /* power domain autosuspend delay 2s */
1395
+ pm_runtime_set_autosuspend_delay(dev, 2000);
1396
+ pm_runtime_use_autosuspend(dev);
1397
+ device_init_wakeup(dev, true);
1398
+ pm_runtime_enable(dev);
1399
+
1400
+ dev_info(dev, "ccu-mode: %d\n", ccu->ccu_mode);
1401
+ return 0;
1402
+}
12511403
12521404 static int rkvdec2_alloc_rcbbuf(struct platform_device *pdev, struct rkvdec2_dev *dec)
12531405 {
....@@ -1342,6 +1494,22 @@
13421494 if (!ret && dec->rcb_min_width)
13431495 dev_info(dev, "min_width %u\n", dec->rcb_min_width);
13441496
1497
+ /* if have, read rcb_info */
1498
+ dec->rcb_info_count = device_property_count_u32(dev, "rockchip,rcb-info");
1499
+ if (dec->rcb_info_count > 0 &&
1500
+ dec->rcb_info_count <= (sizeof(dec->rcb_infos) / sizeof(u32))) {
1501
+ int i;
1502
+
1503
+ ret = device_property_read_u32_array(dev, "rockchip,rcb-info",
1504
+ dec->rcb_infos, dec->rcb_info_count);
1505
+ if (!ret) {
1506
+ dev_info(dev, "rcb_info_count %u\n", dec->rcb_info_count);
1507
+ for (i = 0; i < dec->rcb_info_count; i += 2)
1508
+ dev_info(dev, "[%u, %u]\n",
1509
+ dec->rcb_infos[i], dec->rcb_infos[i+1]);
1510
+ }
1511
+ }
1512
+
13451513 return 0;
13461514
13471515 err_sram_map:
....@@ -1350,7 +1518,94 @@
13501518 return ret;
13511519 }
13521520
1353
-static int rkvdec2_probe(struct platform_device *pdev)
1521
+static int rkvdec2_core_probe(struct platform_device *pdev)
1522
+{
1523
+ int ret;
1524
+ struct rkvdec2_dev *dec;
1525
+ struct mpp_dev *mpp;
1526
+ struct device *dev = &pdev->dev;
1527
+ irq_handler_t irq_proc = NULL;
1528
+
1529
+ dec = devm_kzalloc(dev, sizeof(*dec), GFP_KERNEL);
1530
+ if (!dec)
1531
+ return -ENOMEM;
1532
+
1533
+ mpp = &dec->mpp;
1534
+ platform_set_drvdata(pdev, mpp);
1535
+ mpp->is_irq_startup = false;
1536
+ if (dev->of_node) {
1537
+ struct device_node *np = pdev->dev.of_node;
1538
+ const struct of_device_id *match;
1539
+
1540
+ match = of_match_node(mpp_rkvdec2_dt_match, dev->of_node);
1541
+ if (match)
1542
+ mpp->var = (struct mpp_dev_var *)match->data;
1543
+ mpp->core_id = of_alias_get_id(np, "rkvdec");
1544
+ }
1545
+
1546
+ ret = mpp_dev_probe(mpp, pdev);
1547
+ if (ret) {
1548
+ dev_err(dev, "probe sub driver failed\n");
1549
+ return ret;
1550
+ }
1551
+ dec->mmu_base = ioremap(dec->mpp.io_base + 0x600, 0x80);
1552
+ if (!dec->mmu_base)
1553
+ dev_err(dev, "mmu base map failed!\n");
1554
+
1555
+ /* attach core to ccu */
1556
+ ret = rkvdec2_attach_ccu(dev, dec);
1557
+ if (ret) {
1558
+ dev_err(dev, "attach ccu failed\n");
1559
+ return ret;
1560
+ }
1561
+
1562
+ /* alloc rcb buffer */
1563
+ rkvdec2_alloc_rcbbuf(pdev, dec);
1564
+
1565
+ /* set device for link */
1566
+ ret = rkvdec2_ccu_link_init(pdev, dec);
1567
+ if (ret)
1568
+ return ret;
1569
+
1570
+ mpp->dev_ops->alloc_task = rkvdec2_ccu_alloc_task;
1571
+ if (dec->ccu->ccu_mode == RKVDEC2_CCU_TASK_SOFT) {
1572
+ mpp->dev_ops->task_worker = rkvdec2_soft_ccu_worker;
1573
+ irq_proc = rkvdec2_soft_ccu_irq;
1574
+ mpp->fault_handler = rkvdec2_soft_ccu_iommu_fault_handle;
1575
+ } else if (dec->ccu->ccu_mode == RKVDEC2_CCU_TASK_HARD) {
1576
+ if (mpp->core_id == 0 && mpp->task_capacity > 1) {
1577
+ dec->link_dec->task_capacity = mpp->task_capacity;
1578
+ ret = rkvdec2_ccu_alloc_table(dec, dec->link_dec);
1579
+ if (ret)
1580
+ return ret;
1581
+ }
1582
+ mpp->dev_ops->task_worker = rkvdec2_hard_ccu_worker;
1583
+ irq_proc = rkvdec2_hard_ccu_irq;
1584
+ mpp->fault_handler = rkvdec2_hard_ccu_iommu_fault_handle;
1585
+ }
1586
+ kthread_init_work(&mpp->work, mpp->dev_ops->task_worker);
1587
+
1588
+ /* get irq request */
1589
+ ret = devm_request_threaded_irq(dev, mpp->irq, irq_proc, NULL,
1590
+ IRQF_SHARED, dev_name(dev), mpp);
1591
+ if (ret) {
1592
+ dev_err(dev, "register interrupter runtime failed\n");
1593
+ return -EINVAL;
1594
+ }
1595
+ /*make sure mpp->irq is startup then can be en/disable*/
1596
+ mpp->is_irq_startup = true;
1597
+
1598
+ mpp->session_max_buffers = RKVDEC_SESSION_MAX_BUFFERS;
1599
+ rkvdec2_procfs_init(mpp);
1600
+
1601
+ /* if is main-core, register to mpp service */
1602
+ if (mpp->core_id == 0)
1603
+ mpp_dev_register_srv(mpp, mpp->srv);
1604
+
1605
+ return ret;
1606
+}
1607
+
1608
+static int rkvdec2_probe_default(struct platform_device *pdev)
13541609 {
13551610 struct device *dev = &pdev->dev;
13561611 struct rkvdec2_dev *dec = NULL;
....@@ -1358,13 +1613,12 @@
13581613 const struct of_device_id *match = NULL;
13591614 int ret = 0;
13601615
1361
- dev_info(dev, "probing start\n");
13621616 dec = devm_kzalloc(dev, sizeof(*dec), GFP_KERNEL);
13631617 if (!dec)
13641618 return -ENOMEM;
13651619
13661620 mpp = &dec->mpp;
1367
- platform_set_drvdata(pdev, dec);
1621
+ platform_set_drvdata(pdev, mpp);
13681622
13691623 if (pdev->dev.of_node) {
13701624 match = of_match_node(mpp_rkvdec2_dt_match, pdev->dev.of_node);
....@@ -1405,9 +1659,28 @@
14051659 rkvdec2_link_procfs_init(mpp);
14061660 /* register current device to mpp service */
14071661 mpp_dev_register_srv(mpp, mpp->srv);
1662
+
1663
+ return ret;
1664
+}
1665
+
1666
+static int rkvdec2_probe(struct platform_device *pdev)
1667
+{
1668
+ int ret;
1669
+ struct device *dev = &pdev->dev;
1670
+ struct device_node *np = dev->of_node;
1671
+
1672
+ dev_info(dev, "%s, probing start\n", np->name);
1673
+
1674
+ if (strstr(np->name, "ccu"))
1675
+ ret = rkvdec2_ccu_probe(pdev);
1676
+ else if (strstr(np->name, "core"))
1677
+ ret = rkvdec2_core_probe(pdev);
1678
+ else
1679
+ ret = rkvdec2_probe_default(pdev);
1680
+
14081681 dev_info(dev, "probing finish\n");
14091682
1410
- return 0;
1683
+ return ret;
14111684 }
14121685
14131686 static int rkvdec2_free_rcbbuf(struct platform_device *pdev, struct rkvdec2_dev *dec)
....@@ -1416,8 +1689,9 @@
14161689
14171690 if (dec->rcb_page) {
14181691 size_t page_size = PAGE_ALIGN(dec->rcb_size - dec->sram_size);
1692
+ int order = min(get_order(page_size), MAX_ORDER);
14191693
1420
- __free_pages(dec->rcb_page, get_order(page_size));
1694
+ __free_pages(dec->rcb_page, order);
14211695 }
14221696 if (dec->rcb_iova) {
14231697 domain = dec->mpp.iommu_info->domain;
....@@ -1430,34 +1704,88 @@
14301704 static int rkvdec2_remove(struct platform_device *pdev)
14311705 {
14321706 struct device *dev = &pdev->dev;
1433
- struct rkvdec2_dev *dec = platform_get_drvdata(pdev);
14341707
1435
- dev_info(dev, "remove device\n");
1436
- rkvdec2_free_rcbbuf(pdev, dec);
1437
- mpp_dev_remove(&dec->mpp);
1438
- rkvdec2_procfs_remove(&dec->mpp);
1439
- rkvdec2_link_remove(&dec->mpp, dec->link_dec);
1708
+ if (strstr(dev_name(dev), "ccu")) {
1709
+ dev_info(dev, "remove ccu device\n");
1710
+ rkvdec2_ccu_remove(dev);
1711
+ } else {
1712
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
1713
+ struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
1714
+
1715
+ dev_info(dev, "remove device\n");
1716
+ if (dec->mmu_base) {
1717
+ iounmap(dec->mmu_base);
1718
+ dec->mmu_base = NULL;
1719
+ }
1720
+ rkvdec2_free_rcbbuf(pdev, dec);
1721
+ mpp_dev_remove(mpp);
1722
+ rkvdec2_procfs_remove(mpp);
1723
+ rkvdec2_link_remove(mpp, dec->link_dec);
1724
+ }
14401725
14411726 return 0;
14421727 }
14431728
14441729 static void rkvdec2_shutdown(struct platform_device *pdev)
14451730 {
1446
- int ret;
1447
- int val;
14481731 struct device *dev = &pdev->dev;
1449
- struct rkvdec2_dev *dec = platform_get_drvdata(pdev);
1450
- struct mpp_dev *mpp = &dec->mpp;
14511732
1452
- dev_info(dev, "shutdown device\n");
1453
-
1454
- atomic_inc(&mpp->srv->shutdown_request);
1455
- ret = readx_poll_timeout(atomic_read,
1456
- &mpp->task_count,
1457
- val, val == 0, 20000, 200000);
1458
- if (ret == -ETIMEDOUT)
1459
- dev_err(dev, "wait total running time out\n");
1733
+ if (!strstr(dev_name(dev), "ccu"))
1734
+ mpp_dev_shutdown(pdev);
14601735 }
1736
+
1737
+static int __maybe_unused rkvdec2_runtime_suspend(struct device *dev)
1738
+{
1739
+ if (strstr(dev_name(dev), "ccu")) {
1740
+ struct rkvdec2_ccu *ccu = dev_get_drvdata(dev);
1741
+
1742
+ mpp_clk_safe_disable(ccu->aclk_info.clk);
1743
+ } else {
1744
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
1745
+
1746
+ if (mpp->is_irq_startup) {
1747
+ /* disable core irq */
1748
+ disable_irq(mpp->irq);
1749
+ if (mpp->iommu_info && mpp->iommu_info->got_irq)
1750
+ /* disable mmu irq */
1751
+ disable_irq(mpp->iommu_info->irq);
1752
+ }
1753
+
1754
+ if (mpp->hw_ops->clk_off)
1755
+ mpp->hw_ops->clk_off(mpp);
1756
+ }
1757
+
1758
+ return 0;
1759
+}
1760
+
1761
+static int __maybe_unused rkvdec2_runtime_resume(struct device *dev)
1762
+{
1763
+ if (strstr(dev_name(dev), "ccu")) {
1764
+ struct rkvdec2_ccu *ccu = dev_get_drvdata(dev);
1765
+
1766
+ mpp_clk_safe_enable(ccu->aclk_info.clk);
1767
+ } else {
1768
+ struct mpp_dev *mpp = dev_get_drvdata(dev);
1769
+
1770
+ if (mpp->hw_ops->clk_on)
1771
+ mpp->hw_ops->clk_on(mpp);
1772
+ if (mpp->is_irq_startup) {
1773
+ /* enable core irq */
1774
+ enable_irq(mpp->irq);
1775
+ /* enable mmu irq */
1776
+ if (mpp->iommu_info && mpp->iommu_info->got_irq)
1777
+ enable_irq(mpp->iommu_info->irq);
1778
+ }
1779
+
1780
+ }
1781
+
1782
+ return 0;
1783
+}
1784
+
1785
+static const struct dev_pm_ops rkvdec2_pm_ops = {
1786
+ SET_RUNTIME_PM_OPS(rkvdec2_runtime_suspend, rkvdec2_runtime_resume, NULL)
1787
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
1788
+};
14611789
14621790 struct platform_driver rockchip_rkvdec2_driver = {
14631791 .probe = rkvdec2_probe,
....@@ -1466,6 +1794,7 @@
14661794 .driver = {
14671795 .name = RKVDEC_DRIVER_NAME,
14681796 .of_match_table = of_match_ptr(mpp_rkvdec2_dt_match),
1797
+ .pm = &rkvdec2_pm_ops,
14691798 },
14701799 };
14711800 EXPORT_SYMBOL(rockchip_rkvdec2_driver);