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"
....@@ -17,11 +19,13 @@
1719
1820 #include <linux/devfreq_cooling.h>
1921 #include <soc/rockchip/rockchip_ipa.h>
22
+#include <soc/rockchip/rockchip_dmc.h>
2023 #include <soc/rockchip/rockchip_opp_select.h>
2124 #include <soc/rockchip/rockchip_system_monitor.h>
25
+#include <soc/rockchip/rockchip_iommu.h>
2226
2327 #ifdef CONFIG_PM_DEVFREQ
24
-#include "../../../devfreq/governor.h"
28
+#include "../drivers/devfreq/governor.h"
2529 #endif
2630
2731 /*
....@@ -36,13 +40,22 @@
3640 .link_info = &rkvdec_link_v2_hw_info,
3741 };
3842
39
-static struct mpp_hw_info rkvdec_rk3568_hw_info = {
43
+static struct mpp_hw_info rkvdec_rk356x_hw_info = {
4044 .reg_num = RKVDEC_REG_NUM,
4145 .reg_id = RKVDEC_REG_HW_ID_INDEX,
4246 .reg_start = RKVDEC_REG_START_INDEX,
4347 .reg_end = RKVDEC_REG_END_INDEX,
4448 .reg_en = RKVDEC_REG_START_EN_INDEX,
45
- .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,
4659 };
4760
4861 /*
....@@ -180,9 +193,8 @@
180193 return 0;
181194 }
182195
183
-static int mpp_set_rcbbuf(struct mpp_dev *mpp,
184
- struct mpp_session *session,
185
- struct rkvdec2_task *task)
196
+int mpp_set_rcbbuf(struct mpp_dev *mpp, struct mpp_session *session,
197
+ struct mpp_task *task)
186198 {
187199 struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
188200 struct rkvdec2_session_priv *priv = session->priv;
....@@ -202,10 +214,11 @@
202214 for (i = 0; i < rcb_inf->cnt; i++) {
203215 reg_idx = rcb_inf->elem[i].index;
204216 rcb_size = rcb_inf->elem[i].size;
205
- if (!rcb_size ||
206
- rcb_offset > dec->sram_size ||
207
- (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);
208220 continue;
221
+ }
209222 mpp_debug(DEBUG_SRAM_INFO, "rcb: reg %d offset %d, size %d\n",
210223 reg_idx, rcb_offset, rcb_size);
211224 task->reg[reg_idx] = dec->rcb_iova + rcb_offset;
....@@ -218,45 +231,38 @@
218231 return 0;
219232 }
220233
221
-void *rkvdec2_alloc_task(struct mpp_session *session,
222
- 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)
223236 {
224237 int ret;
225
- struct mpp_task *mpp_task = NULL;
226
- struct rkvdec2_task *task = NULL;
227
- struct mpp_dev *mpp = session->mpp;
238
+ struct mpp_task *mpp_task = &task->mpp_task;
228239
229240 mpp_debug_enter();
230241
231
- task = kzalloc(sizeof(*task), GFP_KERNEL);
232
- if (!task)
233
- return NULL;
234
-
235
- mpp_task = &task->mpp_task;
236242 mpp_task_init(session, mpp_task);
237243 mpp_task->hw_info = mpp->var->hw_info;
238244 mpp_task->reg = task->reg;
239245 /* extract reqs for current task */
240246 ret = rkvdec2_extract_task_msg(session, task, msgs);
241247 if (ret)
242
- goto fail;
248
+ return ret;
243249
244250 /* process fd in register */
245251 if (!(msgs->flags & MPP_FLAGS_REG_FD_NO_TRANS)) {
246252 u32 fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_FORMAT_INDEX]);
247253
248
- ret = mpp_translate_reg_address(session, &task->mpp_task,
254
+ ret = mpp_translate_reg_address(session, mpp_task,
249255 fmt, task->reg, &task->off_inf);
250256 if (ret)
251257 goto fail;
252258
253
- 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);
254260 }
255
- mpp_set_rcbbuf(mpp, session, task);
261
+
256262 task->strm_addr = task->reg[RKVDEC_REG_RLC_BASE_INDEX];
257263 task->clk_mode = CLK_MODE_NORMAL;
258264 task->slot_idx = -1;
259
- init_waitqueue_head(&task->wait);
265
+ init_waitqueue_head(&mpp_task->wait);
260266 /* get resolution info */
261267 if (session->priv) {
262268 struct rkvdec2_session_priv *priv = session->priv;
....@@ -272,18 +278,37 @@
272278
273279 mpp_debug_leave();
274280
275
- return mpp_task;
281
+ return 0;
276282
277283 fail:
278284 mpp_task_dump_mem_region(mpp, mpp_task);
279285 mpp_task_dump_reg(mpp, mpp_task);
280286 mpp_task_finalize(session, mpp_task);
281
- kfree(task);
282
- 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;
283308 }
284309
285310 static void *rkvdec2_rk3568_alloc_task(struct mpp_session *session,
286
- struct mpp_task_msgs *msgs)
311
+ struct mpp_task_msgs *msgs)
287312 {
288313 u32 fmt;
289314 struct mpp_task *mpp_task = NULL;
....@@ -304,6 +329,7 @@
304329 static int rkvdec2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task)
305330 {
306331 struct rkvdec2_task *task = to_rkvdec2_task(mpp_task);
332
+ u32 timing_en = mpp->srv->timing_en;
307333 u32 reg_en = mpp_task->hw_info->reg_en;
308334 /* set cache size */
309335 u32 reg = RKVDEC_CACHE_PERMIT_CACHEABLE_ACCESS |
....@@ -332,12 +358,20 @@
332358 e = s + req->size / sizeof(u32);
333359 mpp_write_req(mpp, task->reg, s, e, reg_en);
334360 }
361
+
362
+ /* flush tlb before starting hardware */
363
+ mpp_iommu_flush_tlb(mpp->iommu_info);
364
+
335365 /* init current task */
336366 mpp->cur_task = mpp_task;
337
- mpp_time_record(mpp_task);
367
+
368
+ mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY);
369
+
338370 /* Flush the register before the start the device */
339371 wmb();
340372 mpp_write(mpp, RKVDEC_REG_START_EN_BASE, task->reg[reg_en] | RKVDEC_START_EN);
373
+
374
+ mpp_task_run_end(mpp_task, timing_en);
341375
342376 mpp_debug_leave();
343377
....@@ -381,13 +415,15 @@
381415 u32 err_mask;
382416 struct rkvdec2_task *task = NULL;
383417 struct mpp_task *mpp_task = mpp->cur_task;
418
+ struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
384419
385420 /* FIXME use a spin lock here */
386421 if (!mpp_task) {
387422 dev_err(mpp->dev, "no current task\n");
388423 return IRQ_HANDLED;
389424 }
390
- mpp_time_diff(mpp_task);
425
+ mpp_task->hw_cycles = mpp_read(mpp, RKVDEC_PERF_WORKING_CNT);
426
+ mpp_time_diff_with_hw_time(mpp_task, dec->cycle_clk->real_rate_hz);
391427 mpp->cur_task = NULL;
392428 task = to_rkvdec2_task(mpp_task);
393429 task->irq_status = mpp->irq_status;
....@@ -397,9 +433,10 @@
397433 RKVDEC_TIMEOUT_STA | RKVDEC_ERROR_STA;
398434 if (err_mask & task->irq_status) {
399435 atomic_inc(&mpp->reset_request);
400
- mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n",
401
- task->irq_status);
402
- 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
+ }
403440 }
404441
405442 mpp_task_finish(mpp_task->session, mpp_task);
....@@ -470,6 +507,18 @@
470507 dec_length = dec_get - task->strm_addr;
471508 task->reg[RKVDEC_REG_RLC_BASE_INDEX] = dec_length << 10;
472509 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
+ }
473522
474523 mpp_debug_leave();
475524
....@@ -610,13 +659,24 @@
610659 static int rkvdec2_procfs_init(struct mpp_dev *mpp)
611660 {
612661 struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
662
+ char name[32];
613663
614
- 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);
615671 if (IS_ERR_OR_NULL(dec->procfs)) {
616672 mpp_err("failed on open procfs\n");
617673 dec->procfs = NULL;
618674 return -EIO;
619675 }
676
+
677
+ /* for common mpp_dev options */
678
+ mpp_procfs_create_common(dec->procfs, mpp);
679
+
620680 mpp_procfs_create_u32("aclk", 0644,
621681 dec->procfs, &dec->aclk_info.debug_rate_hz);
622682 mpp_procfs_create_u32("clk_core", 0644,
....@@ -770,7 +830,7 @@
770830 };
771831
772832 static struct monitor_dev_profile vdec2_mdevp = {
773
- .type = MONITOR_TPYE_DEV,
833
+ .type = MONITOR_TYPE_DEV,
774834 .low_temp_adjust = rockchip_monitor_dev_low_temp_adjust,
775835 .high_temp_adjust = rockchip_monitor_dev_high_temp_adjust,
776836 };
....@@ -878,6 +938,42 @@
878938
879939 return 0;
880940 }
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
+}
881977 #endif
882978
883979 static int rkvdec2_init(struct mpp_dev *mpp)
....@@ -910,6 +1006,7 @@
9101006 mpp_set_clk_info_rate_hz(&dec->cabac_clk_info, CLK_MODE_DEFAULT, 200 * MHZ);
9111007 mpp_set_clk_info_rate_hz(&dec->hevc_cabac_clk_info, CLK_MODE_DEFAULT, 300 * MHZ);
9121008
1009
+ dec->cycle_clk = &dec->aclk_info;
9131010 /* Get normal max workload from dtsi */
9141011 of_property_read_u32(mpp->dev->of_node,
9151012 "rockchip,default-max-load", &dec->default_max_load);
....@@ -936,11 +1033,10 @@
9361033 if (!dec->rst_hevc_cabac)
9371034 mpp_err("No hevc cabac reset resource define\n");
9381035
939
-#ifdef CONFIG_PM_DEVFREQ
9401036 ret = rkvdec2_devfreq_init(mpp);
9411037 if (ret)
9421038 mpp_err("failed to add vdec devfreq\n");
943
-#endif
1039
+
9441040 return ret;
9451041 }
9461042
....@@ -965,9 +1061,7 @@
9651061 {
9661062 struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
9671063
968
-#ifdef CONFIG_PM_DEVFREQ
9691064 rkvdec2_devfreq_remove(mpp);
970
-#endif
9711065
9721066 if (dec->fix)
9731067 mpp_dma_free(dec->fix);
....@@ -1046,38 +1140,61 @@
10461140 mpp_clk_set_rate(&dec->aclk_info, task->clk_mode);
10471141 mpp_clk_set_rate(&dec->cabac_clk_info, task->clk_mode);
10481142 mpp_clk_set_rate(&dec->hevc_cabac_clk_info, task->clk_mode);
1049
-
1050
-#ifdef CONFIG_PM_DEVFREQ
1051
- if (dec->devfreq) {
1052
- unsigned long core_rate_hz;
1053
-
1054
- mutex_lock(&dec->devfreq->lock);
1055
- core_rate_hz = mpp_get_clk_info_rate_hz(&dec->core_clk_info, task->clk_mode);
1056
- if (dec->core_rate_hz != core_rate_hz) {
1057
- dec->core_rate_hz = core_rate_hz;
1058
- update_devfreq(dec->devfreq);
1059
- }
1060
- mutex_unlock(&dec->devfreq->lock);
1061
-
1062
- return 0;
1063
- }
1064
-#endif
1065
- mpp_clk_set_rate(&dec->core_clk_info, task->clk_mode);
1143
+ mpp_devfreq_set_core_rate(mpp, task->clk_mode);
10661144
10671145 return 0;
10681146 }
10691147
1070
-static int rkvdec2_reset(struct mpp_dev *mpp)
1148
+static int rkvdec2_soft_reset(struct mpp_dev *mpp)
1149
+{
1150
+ int ret = 0;
1151
+
1152
+ /*
1153
+ * for rk3528 and rk3562
1154
+ * use mmu reset instead of rkvdec soft reset
1155
+ * rkvdec will reset together when rkvdec_mmu force reset
1156
+ */
1157
+ ret = rockchip_iommu_force_reset(mpp->dev);
1158
+ if (ret)
1159
+ mpp_err("soft mmu reset fail, ret %d\n", ret);
1160
+ mpp_write(mpp, RKVDEC_REG_INT_EN, 0);
1161
+
1162
+ return ret;
1163
+
1164
+}
1165
+
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)
10711185 {
10721186 struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
1187
+ int ret = 0;
10731188
10741189 mpp_debug_enter();
1075
-#ifdef CONFIG_PM_DEVFREQ
1076
- if (dec->devfreq)
1077
- mutex_lock(&dec->devfreq->lock);
1078
-#endif
1079
- if (dec->rst_a && dec->rst_h) {
1080
- rockchip_pmu_idle_request(mpp->dev, true);
1190
+
1191
+ /* safe reset first*/
1192
+ ret = rkvdec2_soft_reset(mpp);
1193
+
1194
+ /* cru reset */
1195
+ if (ret && dec->rst_a && dec->rst_h) {
1196
+ mpp_err("soft reset timeout, use cru reset\n");
1197
+ mpp_pmu_idle_request(mpp, true);
10811198 mpp_safe_reset(dec->rst_niu_a);
10821199 mpp_safe_reset(dec->rst_niu_h);
10831200 mpp_safe_reset(dec->rst_a);
....@@ -1093,12 +1210,8 @@
10931210 mpp_safe_unreset(dec->rst_core);
10941211 mpp_safe_unreset(dec->rst_cabac);
10951212 mpp_safe_unreset(dec->rst_hevc_cabac);
1096
- rockchip_pmu_idle_request(mpp->dev, false);
1213
+ mpp_pmu_idle_request(mpp, false);
10971214 }
1098
-#ifdef CONFIG_PM_DEVFREQ
1099
- if (dec->devfreq)
1100
- mutex_unlock(&dec->devfreq->lock);
1101
-#endif
11021215 mpp_debug_leave();
11031216
11041217 return 0;
....@@ -1120,7 +1233,16 @@
11201233 .clk_off = rkvdec2_clk_off,
11211234 .get_freq = rkvdec2_get_freq,
11221235 .set_freq = rkvdec2_set_freq,
1123
- .reset = rkvdec2_reset,
1236
+ .reset = rkvdec2_sip_reset,
1237
+};
1238
+
1239
+static struct mpp_hw_ops rkvdec_rk3588_hw_ops = {
1240
+ .init = rkvdec2_init,
1241
+ .clk_on = rkvdec2_clk_on,
1242
+ .clk_off = rkvdec2_clk_off,
1243
+ .get_freq = rkvdec2_get_freq,
1244
+ .set_freq = rkvdec2_set_freq,
1245
+ .reset = rkvdec2_sip_reset,
11241246 };
11251247
11261248 static struct mpp_dev_ops rkvdec_v2_dev_ops = {
....@@ -1160,10 +1282,26 @@
11601282
11611283 static const struct mpp_dev_var rkvdec_rk3568_data = {
11621284 .device_type = MPP_DEVICE_RKVDEC,
1163
- .hw_info = &rkvdec_rk3568_hw_info,
1285
+ .hw_info = &rkvdec_rk356x_hw_info,
11641286 .trans_info = rkvdec_v2_trans,
11651287 .hw_ops = &rkvdec_rk3568_hw_ops,
11661288 .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,
11671305 };
11681306
11691307 static const struct of_device_id mpp_rkvdec2_dt_match[] = {
....@@ -1177,8 +1315,91 @@
11771315 .data = &rkvdec_rk3568_data,
11781316 },
11791317 #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
11801336 {},
11811337 };
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
+}
11821403
11831404 static int rkvdec2_alloc_rcbbuf(struct platform_device *pdev, struct rkvdec2_dev *dec)
11841405 {
....@@ -1273,6 +1494,22 @@
12731494 if (!ret && dec->rcb_min_width)
12741495 dev_info(dev, "min_width %u\n", dec->rcb_min_width);
12751496
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
+
12761513 return 0;
12771514
12781515 err_sram_map:
....@@ -1281,7 +1518,94 @@
12811518 return ret;
12821519 }
12831520
1284
-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)
12851609 {
12861610 struct device *dev = &pdev->dev;
12871611 struct rkvdec2_dev *dec = NULL;
....@@ -1289,13 +1613,12 @@
12891613 const struct of_device_id *match = NULL;
12901614 int ret = 0;
12911615
1292
- dev_info(dev, "probing start\n");
12931616 dec = devm_kzalloc(dev, sizeof(*dec), GFP_KERNEL);
12941617 if (!dec)
12951618 return -ENOMEM;
12961619
12971620 mpp = &dec->mpp;
1298
- platform_set_drvdata(pdev, dec);
1621
+ platform_set_drvdata(pdev, mpp);
12991622
13001623 if (pdev->dev.of_node) {
13011624 match = of_match_node(mpp_rkvdec2_dt_match, pdev->dev.of_node);
....@@ -1336,9 +1659,28 @@
13361659 rkvdec2_link_procfs_init(mpp);
13371660 /* register current device to mpp service */
13381661 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
+
13391681 dev_info(dev, "probing finish\n");
13401682
1341
- return 0;
1683
+ return ret;
13421684 }
13431685
13441686 static int rkvdec2_free_rcbbuf(struct platform_device *pdev, struct rkvdec2_dev *dec)
....@@ -1347,8 +1689,9 @@
13471689
13481690 if (dec->rcb_page) {
13491691 size_t page_size = PAGE_ALIGN(dec->rcb_size - dec->sram_size);
1692
+ int order = min(get_order(page_size), MAX_ORDER);
13501693
1351
- __free_pages(dec->rcb_page, get_order(page_size));
1694
+ __free_pages(dec->rcb_page, order);
13521695 }
13531696 if (dec->rcb_iova) {
13541697 domain = dec->mpp.iommu_info->domain;
....@@ -1361,34 +1704,88 @@
13611704 static int rkvdec2_remove(struct platform_device *pdev)
13621705 {
13631706 struct device *dev = &pdev->dev;
1364
- struct rkvdec2_dev *dec = platform_get_drvdata(pdev);
13651707
1366
- dev_info(dev, "remove device\n");
1367
- rkvdec2_free_rcbbuf(pdev, dec);
1368
- mpp_dev_remove(&dec->mpp);
1369
- rkvdec2_procfs_remove(&dec->mpp);
1370
- 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
+ }
13711725
13721726 return 0;
13731727 }
13741728
13751729 static void rkvdec2_shutdown(struct platform_device *pdev)
13761730 {
1377
- int ret;
1378
- int val;
13791731 struct device *dev = &pdev->dev;
1380
- struct rkvdec2_dev *dec = platform_get_drvdata(pdev);
1381
- struct mpp_dev *mpp = &dec->mpp;
13821732
1383
- dev_info(dev, "shutdown device\n");
1384
-
1385
- atomic_inc(&mpp->srv->shutdown_request);
1386
- ret = readx_poll_timeout(atomic_read,
1387
- &mpp->task_count,
1388
- val, val == 0, 20000, 200000);
1389
- if (ret == -ETIMEDOUT)
1390
- dev_err(dev, "wait total running time out\n");
1733
+ if (!strstr(dev_name(dev), "ccu"))
1734
+ mpp_dev_shutdown(pdev);
13911735 }
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
+};
13921789
13931790 struct platform_driver rockchip_rkvdec2_driver = {
13941791 .probe = rkvdec2_probe,
....@@ -1397,6 +1794,7 @@
13971794 .driver = {
13981795 .name = RKVDEC_DRIVER_NAME,
13991796 .of_match_table = of_match_ptr(mpp_rkvdec2_dt_match),
1797
+ .pm = &rkvdec2_pm_ops,
14001798 },
14011799 };
14021800 EXPORT_SYMBOL(rockchip_rkvdec2_driver);