.. | .. |
---|
7 | 7 | * Ding Wei, leo.ding@rock-chips.com |
---|
8 | 8 | * |
---|
9 | 9 | */ |
---|
| 10 | +#include <linux/pm_runtime.h> |
---|
| 11 | + |
---|
10 | 12 | #include "mpp_debug.h" |
---|
11 | 13 | #include "mpp_common.h" |
---|
12 | 14 | #include "mpp_iommu.h" |
---|
.. | .. |
---|
23 | 25 | #include <soc/rockchip/rockchip_iommu.h> |
---|
24 | 26 | |
---|
25 | 27 | #ifdef CONFIG_PM_DEVFREQ |
---|
26 | | -#include "../../../devfreq/governor.h" |
---|
| 28 | +#include "../drivers/devfreq/governor.h" |
---|
27 | 29 | #endif |
---|
28 | 30 | |
---|
29 | 31 | /* |
---|
.. | .. |
---|
38 | 40 | .link_info = &rkvdec_link_v2_hw_info, |
---|
39 | 41 | }; |
---|
40 | 42 | |
---|
41 | | -static struct mpp_hw_info rkvdec_rk3568_hw_info = { |
---|
| 43 | +static struct mpp_hw_info rkvdec_rk356x_hw_info = { |
---|
42 | 44 | .reg_num = RKVDEC_REG_NUM, |
---|
43 | 45 | .reg_id = RKVDEC_REG_HW_ID_INDEX, |
---|
44 | 46 | .reg_start = RKVDEC_REG_START_INDEX, |
---|
45 | 47 | .reg_end = RKVDEC_REG_END_INDEX, |
---|
46 | 48 | .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, |
---|
48 | 59 | }; |
---|
49 | 60 | |
---|
50 | 61 | /* |
---|
.. | .. |
---|
182 | 193 | return 0; |
---|
183 | 194 | } |
---|
184 | 195 | |
---|
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) |
---|
188 | 198 | { |
---|
189 | 199 | struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); |
---|
190 | 200 | struct rkvdec2_session_priv *priv = session->priv; |
---|
.. | .. |
---|
204 | 214 | for (i = 0; i < rcb_inf->cnt; i++) { |
---|
205 | 215 | reg_idx = rcb_inf->elem[i].index; |
---|
206 | 216 | 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); |
---|
210 | 220 | continue; |
---|
| 221 | + } |
---|
211 | 222 | mpp_debug(DEBUG_SRAM_INFO, "rcb: reg %d offset %d, size %d\n", |
---|
212 | 223 | reg_idx, rcb_offset, rcb_size); |
---|
213 | 224 | task->reg[reg_idx] = dec->rcb_iova + rcb_offset; |
---|
.. | .. |
---|
220 | 231 | return 0; |
---|
221 | 232 | } |
---|
222 | 233 | |
---|
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) |
---|
225 | 236 | { |
---|
226 | 237 | 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; |
---|
230 | 239 | |
---|
231 | 240 | mpp_debug_enter(); |
---|
232 | 241 | |
---|
233 | | - task = kzalloc(sizeof(*task), GFP_KERNEL); |
---|
234 | | - if (!task) |
---|
235 | | - return NULL; |
---|
236 | | - |
---|
237 | | - mpp_task = &task->mpp_task; |
---|
238 | 242 | mpp_task_init(session, mpp_task); |
---|
239 | 243 | mpp_task->hw_info = mpp->var->hw_info; |
---|
240 | 244 | mpp_task->reg = task->reg; |
---|
241 | 245 | /* extract reqs for current task */ |
---|
242 | 246 | ret = rkvdec2_extract_task_msg(session, task, msgs); |
---|
243 | 247 | if (ret) |
---|
244 | | - goto fail; |
---|
| 248 | + return ret; |
---|
245 | 249 | |
---|
246 | 250 | /* process fd in register */ |
---|
247 | 251 | if (!(msgs->flags & MPP_FLAGS_REG_FD_NO_TRANS)) { |
---|
248 | 252 | u32 fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_FORMAT_INDEX]); |
---|
249 | 253 | |
---|
250 | | - ret = mpp_translate_reg_address(session, &task->mpp_task, |
---|
| 254 | + ret = mpp_translate_reg_address(session, mpp_task, |
---|
251 | 255 | fmt, task->reg, &task->off_inf); |
---|
252 | 256 | if (ret) |
---|
253 | 257 | goto fail; |
---|
254 | 258 | |
---|
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); |
---|
256 | 260 | } |
---|
257 | | - mpp_set_rcbbuf(mpp, session, task); |
---|
| 261 | + |
---|
258 | 262 | task->strm_addr = task->reg[RKVDEC_REG_RLC_BASE_INDEX]; |
---|
259 | 263 | task->clk_mode = CLK_MODE_NORMAL; |
---|
260 | 264 | task->slot_idx = -1; |
---|
261 | | - init_waitqueue_head(&task->wait); |
---|
| 265 | + init_waitqueue_head(&mpp_task->wait); |
---|
262 | 266 | /* get resolution info */ |
---|
263 | 267 | if (session->priv) { |
---|
264 | 268 | struct rkvdec2_session_priv *priv = session->priv; |
---|
.. | .. |
---|
274 | 278 | |
---|
275 | 279 | mpp_debug_leave(); |
---|
276 | 280 | |
---|
277 | | - return mpp_task; |
---|
| 281 | + return 0; |
---|
278 | 282 | |
---|
279 | 283 | fail: |
---|
280 | 284 | mpp_task_dump_mem_region(mpp, mpp_task); |
---|
281 | 285 | mpp_task_dump_reg(mpp, mpp_task); |
---|
282 | 286 | 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; |
---|
285 | 308 | } |
---|
286 | 309 | |
---|
287 | 310 | static void *rkvdec2_rk3568_alloc_task(struct mpp_session *session, |
---|
288 | | - struct mpp_task_msgs *msgs) |
---|
| 311 | + struct mpp_task_msgs *msgs) |
---|
289 | 312 | { |
---|
290 | 313 | u32 fmt; |
---|
291 | 314 | struct mpp_task *mpp_task = NULL; |
---|
.. | .. |
---|
400 | 423 | return IRQ_HANDLED; |
---|
401 | 424 | } |
---|
402 | 425 | 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); |
---|
404 | 427 | mpp->cur_task = NULL; |
---|
405 | 428 | task = to_rkvdec2_task(mpp_task); |
---|
406 | 429 | task->irq_status = mpp->irq_status; |
---|
.. | .. |
---|
410 | 433 | RKVDEC_TIMEOUT_STA | RKVDEC_ERROR_STA; |
---|
411 | 434 | if (err_mask & task->irq_status) { |
---|
412 | 435 | 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 | + } |
---|
416 | 440 | } |
---|
417 | 441 | |
---|
418 | 442 | mpp_task_finish(mpp_task->session, mpp_task); |
---|
.. | .. |
---|
483 | 507 | dec_length = dec_get - task->strm_addr; |
---|
484 | 508 | task->reg[RKVDEC_REG_RLC_BASE_INDEX] = dec_length << 10; |
---|
485 | 509 | 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 | + } |
---|
486 | 522 | |
---|
487 | 523 | mpp_debug_leave(); |
---|
488 | 524 | |
---|
.. | .. |
---|
565 | 601 | } |
---|
566 | 602 | } |
---|
567 | 603 | } 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; |
---|
578 | 604 | default: { |
---|
579 | 605 | mpp_err("unknown mpp ioctl cmd %x\n", req->cmd); |
---|
580 | 606 | } break; |
---|
.. | .. |
---|
633 | 659 | static int rkvdec2_procfs_init(struct mpp_dev *mpp) |
---|
634 | 660 | { |
---|
635 | 661 | struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); |
---|
| 662 | + char name[32]; |
---|
636 | 663 | |
---|
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); |
---|
638 | 671 | if (IS_ERR_OR_NULL(dec->procfs)) { |
---|
639 | 672 | mpp_err("failed on open procfs\n"); |
---|
640 | 673 | dec->procfs = NULL; |
---|
.. | .. |
---|
797 | 830 | }; |
---|
798 | 831 | |
---|
799 | 832 | static struct monitor_dev_profile vdec2_mdevp = { |
---|
800 | | - .type = MONITOR_TPYE_DEV, |
---|
| 833 | + .type = MONITOR_TYPE_DEV, |
---|
801 | 834 | .low_temp_adjust = rockchip_monitor_dev_low_temp_adjust, |
---|
802 | 835 | .high_temp_adjust = rockchip_monitor_dev_high_temp_adjust, |
---|
803 | 836 | }; |
---|
.. | .. |
---|
905 | 938 | |
---|
906 | 939 | return 0; |
---|
907 | 940 | } |
---|
| 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 | +} |
---|
908 | 977 | #endif |
---|
909 | 978 | |
---|
910 | 979 | static int rkvdec2_init(struct mpp_dev *mpp) |
---|
.. | .. |
---|
937 | 1006 | mpp_set_clk_info_rate_hz(&dec->cabac_clk_info, CLK_MODE_DEFAULT, 200 * MHZ); |
---|
938 | 1007 | mpp_set_clk_info_rate_hz(&dec->hevc_cabac_clk_info, CLK_MODE_DEFAULT, 300 * MHZ); |
---|
939 | 1008 | |
---|
| 1009 | + dec->cycle_clk = &dec->aclk_info; |
---|
940 | 1010 | /* Get normal max workload from dtsi */ |
---|
941 | 1011 | of_property_read_u32(mpp->dev->of_node, |
---|
942 | 1012 | "rockchip,default-max-load", &dec->default_max_load); |
---|
.. | .. |
---|
963 | 1033 | if (!dec->rst_hevc_cabac) |
---|
964 | 1034 | mpp_err("No hevc cabac reset resource define\n"); |
---|
965 | 1035 | |
---|
966 | | -#ifdef CONFIG_PM_DEVFREQ |
---|
967 | 1036 | ret = rkvdec2_devfreq_init(mpp); |
---|
968 | 1037 | if (ret) |
---|
969 | 1038 | mpp_err("failed to add vdec devfreq\n"); |
---|
970 | | -#endif |
---|
| 1039 | + |
---|
971 | 1040 | return ret; |
---|
972 | 1041 | } |
---|
973 | 1042 | |
---|
.. | .. |
---|
992 | 1061 | { |
---|
993 | 1062 | struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); |
---|
994 | 1063 | |
---|
995 | | -#ifdef CONFIG_PM_DEVFREQ |
---|
996 | 1064 | rkvdec2_devfreq_remove(mpp); |
---|
997 | | -#endif |
---|
998 | 1065 | |
---|
999 | 1066 | if (dec->fix) |
---|
1000 | 1067 | mpp_dma_free(dec->fix); |
---|
.. | .. |
---|
1073 | 1140 | mpp_clk_set_rate(&dec->aclk_info, task->clk_mode); |
---|
1074 | 1141 | mpp_clk_set_rate(&dec->cabac_clk_info, task->clk_mode); |
---|
1075 | 1142 | 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); |
---|
1093 | 1144 | |
---|
1094 | 1145 | return 0; |
---|
1095 | 1146 | } |
---|
.. | .. |
---|
1112 | 1163 | |
---|
1113 | 1164 | } |
---|
1114 | 1165 | |
---|
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) |
---|
1116 | 1185 | { |
---|
1117 | 1186 | struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); |
---|
1118 | 1187 | int ret = 0; |
---|
1119 | 1188 | |
---|
1120 | 1189 | mpp_debug_enter(); |
---|
1121 | | -#ifdef CONFIG_PM_DEVFREQ |
---|
1122 | | - if (dec->devfreq) |
---|
1123 | | - mutex_lock(&dec->devfreq->lock); |
---|
1124 | | -#endif |
---|
| 1190 | + |
---|
1125 | 1191 | /* safe reset first*/ |
---|
1126 | 1192 | ret = rkvdec2_soft_reset(mpp); |
---|
1127 | 1193 | |
---|
.. | .. |
---|
1146 | 1212 | mpp_safe_unreset(dec->rst_hevc_cabac); |
---|
1147 | 1213 | mpp_pmu_idle_request(mpp, false); |
---|
1148 | 1214 | } |
---|
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 | | - |
---|
1171 | 1215 | mpp_debug_leave(); |
---|
1172 | 1216 | |
---|
1173 | 1217 | return 0; |
---|
.. | .. |
---|
1185 | 1229 | static struct mpp_hw_ops rkvdec_rk3568_hw_ops = { |
---|
1186 | 1230 | .init = rkvdec2_rk3568_init, |
---|
1187 | 1231 | .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, |
---|
1188 | 1241 | .clk_on = rkvdec2_clk_on, |
---|
1189 | 1242 | .clk_off = rkvdec2_clk_off, |
---|
1190 | 1243 | .get_freq = rkvdec2_get_freq, |
---|
.. | .. |
---|
1229 | 1282 | |
---|
1230 | 1283 | static const struct mpp_dev_var rkvdec_rk3568_data = { |
---|
1231 | 1284 | .device_type = MPP_DEVICE_RKVDEC, |
---|
1232 | | - .hw_info = &rkvdec_rk3568_hw_info, |
---|
| 1285 | + .hw_info = &rkvdec_rk356x_hw_info, |
---|
1233 | 1286 | .trans_info = rkvdec_v2_trans, |
---|
1234 | 1287 | .hw_ops = &rkvdec_rk3568_hw_ops, |
---|
1235 | 1288 | .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, |
---|
1236 | 1305 | }; |
---|
1237 | 1306 | |
---|
1238 | 1307 | static const struct of_device_id mpp_rkvdec2_dt_match[] = { |
---|
.. | .. |
---|
1246 | 1315 | .data = &rkvdec_rk3568_data, |
---|
1247 | 1316 | }, |
---|
1248 | 1317 | #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 |
---|
1249 | 1336 | {}, |
---|
1250 | 1337 | }; |
---|
| 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 | +} |
---|
1251 | 1403 | |
---|
1252 | 1404 | static int rkvdec2_alloc_rcbbuf(struct platform_device *pdev, struct rkvdec2_dev *dec) |
---|
1253 | 1405 | { |
---|
.. | .. |
---|
1342 | 1494 | if (!ret && dec->rcb_min_width) |
---|
1343 | 1495 | dev_info(dev, "min_width %u\n", dec->rcb_min_width); |
---|
1344 | 1496 | |
---|
| 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 | + |
---|
1345 | 1513 | return 0; |
---|
1346 | 1514 | |
---|
1347 | 1515 | err_sram_map: |
---|
.. | .. |
---|
1350 | 1518 | return ret; |
---|
1351 | 1519 | } |
---|
1352 | 1520 | |
---|
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) |
---|
1354 | 1609 | { |
---|
1355 | 1610 | struct device *dev = &pdev->dev; |
---|
1356 | 1611 | struct rkvdec2_dev *dec = NULL; |
---|
.. | .. |
---|
1358 | 1613 | const struct of_device_id *match = NULL; |
---|
1359 | 1614 | int ret = 0; |
---|
1360 | 1615 | |
---|
1361 | | - dev_info(dev, "probing start\n"); |
---|
1362 | 1616 | dec = devm_kzalloc(dev, sizeof(*dec), GFP_KERNEL); |
---|
1363 | 1617 | if (!dec) |
---|
1364 | 1618 | return -ENOMEM; |
---|
1365 | 1619 | |
---|
1366 | 1620 | mpp = &dec->mpp; |
---|
1367 | | - platform_set_drvdata(pdev, dec); |
---|
| 1621 | + platform_set_drvdata(pdev, mpp); |
---|
1368 | 1622 | |
---|
1369 | 1623 | if (pdev->dev.of_node) { |
---|
1370 | 1624 | match = of_match_node(mpp_rkvdec2_dt_match, pdev->dev.of_node); |
---|
.. | .. |
---|
1405 | 1659 | rkvdec2_link_procfs_init(mpp); |
---|
1406 | 1660 | /* register current device to mpp service */ |
---|
1407 | 1661 | 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 | + |
---|
1408 | 1681 | dev_info(dev, "probing finish\n"); |
---|
1409 | 1682 | |
---|
1410 | | - return 0; |
---|
| 1683 | + return ret; |
---|
1411 | 1684 | } |
---|
1412 | 1685 | |
---|
1413 | 1686 | static int rkvdec2_free_rcbbuf(struct platform_device *pdev, struct rkvdec2_dev *dec) |
---|
.. | .. |
---|
1416 | 1689 | |
---|
1417 | 1690 | if (dec->rcb_page) { |
---|
1418 | 1691 | size_t page_size = PAGE_ALIGN(dec->rcb_size - dec->sram_size); |
---|
| 1692 | + int order = min(get_order(page_size), MAX_ORDER); |
---|
1419 | 1693 | |
---|
1420 | | - __free_pages(dec->rcb_page, get_order(page_size)); |
---|
| 1694 | + __free_pages(dec->rcb_page, order); |
---|
1421 | 1695 | } |
---|
1422 | 1696 | if (dec->rcb_iova) { |
---|
1423 | 1697 | domain = dec->mpp.iommu_info->domain; |
---|
.. | .. |
---|
1430 | 1704 | static int rkvdec2_remove(struct platform_device *pdev) |
---|
1431 | 1705 | { |
---|
1432 | 1706 | struct device *dev = &pdev->dev; |
---|
1433 | | - struct rkvdec2_dev *dec = platform_get_drvdata(pdev); |
---|
1434 | 1707 | |
---|
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 | + } |
---|
1440 | 1725 | |
---|
1441 | 1726 | return 0; |
---|
1442 | 1727 | } |
---|
1443 | 1728 | |
---|
1444 | 1729 | static void rkvdec2_shutdown(struct platform_device *pdev) |
---|
1445 | 1730 | { |
---|
1446 | | - int ret; |
---|
1447 | | - int val; |
---|
1448 | 1731 | struct device *dev = &pdev->dev; |
---|
1449 | | - struct rkvdec2_dev *dec = platform_get_drvdata(pdev); |
---|
1450 | | - struct mpp_dev *mpp = &dec->mpp; |
---|
1451 | 1732 | |
---|
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); |
---|
1460 | 1735 | } |
---|
| 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 | +}; |
---|
1461 | 1789 | |
---|
1462 | 1790 | struct platform_driver rockchip_rkvdec2_driver = { |
---|
1463 | 1791 | .probe = rkvdec2_probe, |
---|
.. | .. |
---|
1466 | 1794 | .driver = { |
---|
1467 | 1795 | .name = RKVDEC_DRIVER_NAME, |
---|
1468 | 1796 | .of_match_table = of_match_ptr(mpp_rkvdec2_dt_match), |
---|
| 1797 | + .pm = &rkvdec2_pm_ops, |
---|
1469 | 1798 | }, |
---|
1470 | 1799 | }; |
---|
1471 | 1800 | EXPORT_SYMBOL(rockchip_rkvdec2_driver); |
---|