.. | .. |
---|
22 | 22 | #include <linux/reset.h> |
---|
23 | 23 | #include <linux/irqreturn.h> |
---|
24 | 24 | #include <linux/poll.h> |
---|
| 25 | +#include <soc/rockchip/pm_domains.h> |
---|
25 | 26 | |
---|
26 | | -#define MHZ (1000 * 1000) |
---|
| 27 | +#define MHZ (1000 * 1000) |
---|
| 28 | +#define MPP_WORK_TIMEOUT_DELAY (500) |
---|
27 | 29 | |
---|
28 | 30 | #define MPP_MAX_MSG_NUM (16) |
---|
29 | 31 | #define MPP_MAX_REG_TRANS_NUM (60) |
---|
.. | .. |
---|
116 | 118 | MPP_CMD_TRANS_FD_TO_IOVA = MPP_CMD_CONTROL_BASE + 1, |
---|
117 | 119 | MPP_CMD_RELEASE_FD = MPP_CMD_CONTROL_BASE + 2, |
---|
118 | 120 | MPP_CMD_SEND_CODEC_INFO = MPP_CMD_CONTROL_BASE + 3, |
---|
| 121 | + MPP_CMD_SET_ERR_REF_HACK = MPP_CMD_CONTROL_BASE + 4, |
---|
119 | 122 | MPP_CMD_CONTROL_BUTT, |
---|
120 | 123 | |
---|
121 | 124 | MPP_CMD_BUTT, |
---|
.. | .. |
---|
199 | 202 | struct mpp_grf_info { |
---|
200 | 203 | u32 offset; |
---|
201 | 204 | u32 val; |
---|
| 205 | + |
---|
| 206 | + /* close mem when module is not working*/ |
---|
| 207 | + u32 mem_offset; |
---|
| 208 | + u32 val_mem_on; |
---|
| 209 | + u32 val_mem_off; |
---|
| 210 | + |
---|
202 | 211 | struct regmap *grf; |
---|
203 | 212 | }; |
---|
204 | 213 | |
---|
.. | .. |
---|
255 | 264 | u32 reduce_rate_hz; |
---|
256 | 265 | /* record last used rate */ |
---|
257 | 266 | u32 used_rate_hz; |
---|
| 267 | + u32 real_rate_hz; |
---|
258 | 268 | }; |
---|
259 | 269 | |
---|
260 | 270 | struct mpp_dev_var { |
---|
.. | .. |
---|
293 | 303 | struct kthread_work work; |
---|
294 | 304 | /* the flag for get/get/reduce freq */ |
---|
295 | 305 | bool auto_freq_en; |
---|
| 306 | + /* the flag for pmu idle request before device reset */ |
---|
| 307 | + bool skip_idle; |
---|
296 | 308 | |
---|
297 | 309 | /* |
---|
298 | 310 | * The task capacity is the task queue length that hardware can accept. |
---|
.. | .. |
---|
322 | 334 | struct mpp_service *srv; |
---|
323 | 335 | |
---|
324 | 336 | struct list_head queue_link; |
---|
| 337 | + |
---|
| 338 | + /* common per-device procfs */ |
---|
| 339 | + u32 timing_check; |
---|
325 | 340 | }; |
---|
326 | 341 | |
---|
327 | 342 | struct mpp_task; |
---|
.. | .. |
---|
338 | 353 | struct mutex pending_lock; |
---|
339 | 354 | /* task pending list in session */ |
---|
340 | 355 | struct list_head pending_list; |
---|
341 | | - /* lock for session task done list */ |
---|
342 | | - struct mutex done_lock; |
---|
343 | | - /* task done list in session */ |
---|
344 | | - struct list_head done_list; |
---|
345 | 356 | |
---|
346 | | - /* event for session wait thread */ |
---|
347 | | - wait_queue_head_t wait; |
---|
348 | 357 | pid_t pid; |
---|
349 | 358 | atomic_t task_count; |
---|
350 | 359 | atomic_t release_request; |
---|
.. | .. |
---|
387 | 396 | TASK_STATE_ABORT = 9, |
---|
388 | 397 | TASK_STATE_ABORT_READY = 10, |
---|
389 | 398 | TASK_STATE_PROC_DONE = 11, |
---|
| 399 | + |
---|
| 400 | + /* timing debug state */ |
---|
| 401 | + TASK_TIMING_CREATE = 16, |
---|
| 402 | + TASK_TIMING_CREATE_END = 17, |
---|
| 403 | + TASK_TIMING_PENDING = 18, |
---|
| 404 | + TASK_TIMING_RUN = 19, |
---|
| 405 | + TASK_TIMING_TO_SCHED = 20, |
---|
| 406 | + TASK_TIMING_RUN_END = 21, |
---|
| 407 | + TASK_TIMING_IRQ = 22, |
---|
| 408 | + TASK_TIMING_TO_CANCEL = 23, |
---|
| 409 | + TASK_TIMING_ISR = 24, |
---|
| 410 | + TASK_TIMING_FINISH = 25, |
---|
390 | 411 | }; |
---|
391 | 412 | |
---|
392 | 413 | /* The context for the a task */ |
---|
.. | .. |
---|
413 | 434 | struct kref ref; |
---|
414 | 435 | |
---|
415 | 436 | /* record context running start time */ |
---|
416 | | - struct timeval start; |
---|
| 437 | + ktime_t start; |
---|
| 438 | + ktime_t part; |
---|
| 439 | + |
---|
| 440 | + /* debug timing */ |
---|
| 441 | + ktime_t on_create; |
---|
| 442 | + ktime_t on_create_end; |
---|
| 443 | + ktime_t on_pending; |
---|
| 444 | + ktime_t on_run; |
---|
| 445 | + ktime_t on_sched_timeout; |
---|
| 446 | + ktime_t on_run_end; |
---|
| 447 | + ktime_t on_irq; |
---|
| 448 | + ktime_t on_cancel_timeout; |
---|
| 449 | + ktime_t on_isr; |
---|
| 450 | + ktime_t on_finish; |
---|
| 451 | + |
---|
417 | 452 | /* hardware info for current task */ |
---|
418 | 453 | struct mpp_hw_info *hw_info; |
---|
419 | 454 | u32 task_index; |
---|
420 | 455 | u32 *reg; |
---|
| 456 | + /* hw cycles */ |
---|
| 457 | + u32 hw_cycles; |
---|
| 458 | + /* event for session wait thread */ |
---|
| 459 | + wait_queue_head_t wait; |
---|
421 | 460 | }; |
---|
422 | 461 | |
---|
423 | 462 | struct mpp_taskqueue { |
---|
.. | .. |
---|
432 | 471 | struct list_head session_attach; |
---|
433 | 472 | /* link to session session_link for detached sessions */ |
---|
434 | 473 | struct list_head session_detach; |
---|
435 | | - u32 detach_count; |
---|
| 474 | + atomic_t detach_count; |
---|
436 | 475 | |
---|
437 | 476 | /* lock for pending list */ |
---|
438 | 477 | struct mutex pending_lock; |
---|
.. | .. |
---|
454 | 493 | * device task capacity which is attached to the taskqueue |
---|
455 | 494 | */ |
---|
456 | 495 | u32 task_capacity; |
---|
| 496 | + |
---|
| 497 | + /* |
---|
| 498 | + * when we need to set grf_mem config to close mem shared by combo modules, |
---|
| 499 | + * use runtime_cnt to make sure every combo module are not working |
---|
| 500 | + */ |
---|
| 501 | + /* lock for runtime counting */ |
---|
| 502 | + struct mutex ref_lock; |
---|
| 503 | + atomic_t runtime_cnt; |
---|
| 504 | + |
---|
457 | 505 | }; |
---|
458 | 506 | |
---|
459 | 507 | struct mpp_reset_group { |
---|
.. | .. |
---|
490 | 538 | struct mutex session_lock; |
---|
491 | 539 | struct list_head session_list; |
---|
492 | 540 | u32 session_count; |
---|
| 541 | + |
---|
| 542 | + /* global timing record flag */ |
---|
| 543 | + u32 timing_en; |
---|
493 | 544 | }; |
---|
494 | 545 | |
---|
495 | 546 | /* |
---|
.. | .. |
---|
580 | 631 | struct mpp_task *task); |
---|
581 | 632 | int mpp_task_finish(struct mpp_session *session, |
---|
582 | 633 | struct mpp_task *task); |
---|
| 634 | +void mpp_task_run_begin(struct mpp_task *task, u32 timing_en, u32 timeout); |
---|
| 635 | +void mpp_task_run_end(struct mpp_task *task, u32 timing_en); |
---|
583 | 636 | int mpp_task_finalize(struct mpp_session *session, |
---|
584 | 637 | struct mpp_task *task); |
---|
585 | 638 | int mpp_task_dump_mem_region(struct mpp_dev *mpp, |
---|
.. | .. |
---|
588 | 641 | struct mpp_task *task); |
---|
589 | 642 | int mpp_task_dump_hw_reg(struct mpp_dev *mpp, |
---|
590 | 643 | struct mpp_task *task); |
---|
| 644 | +void mpp_task_dump_timing(struct mpp_task *task, s64 time_diff); |
---|
| 645 | +void mpp_reg_show(struct mpp_dev *mpp, u32 offset); |
---|
591 | 646 | |
---|
592 | | -int mpp_session_deinit(struct mpp_session *session); |
---|
| 647 | +void mpp_session_deinit(struct mpp_session *session); |
---|
| 648 | +void mpp_session_cleanup_detach(struct mpp_taskqueue *queue, |
---|
| 649 | + struct kthread_work *work); |
---|
593 | 650 | |
---|
594 | 651 | int mpp_dev_probe(struct mpp_dev *mpp, |
---|
595 | 652 | struct platform_device *pdev); |
---|
.. | .. |
---|
613 | 670 | |
---|
614 | 671 | int mpp_time_record(struct mpp_task *task); |
---|
615 | 672 | int mpp_time_diff(struct mpp_task *task); |
---|
| 673 | +int mpp_time_diff_with_hw_time(struct mpp_task *task, u32 clk_hz); |
---|
| 674 | +int mpp_time_part_diff(struct mpp_task *task); |
---|
616 | 675 | |
---|
617 | 676 | int mpp_write_req(struct mpp_dev *mpp, u32 *regs, |
---|
618 | 677 | u32 start_idx, u32 end_idx, u32 en_idx); |
---|
.. | .. |
---|
740 | 799 | return 0; |
---|
741 | 800 | } |
---|
742 | 801 | |
---|
| 802 | +static inline int mpp_pmu_idle_request(struct mpp_dev *mpp, bool idle) |
---|
| 803 | +{ |
---|
| 804 | + if (mpp->skip_idle) |
---|
| 805 | + return 0; |
---|
| 806 | + |
---|
| 807 | + return rockchip_pmu_idle_request(mpp->dev, idle); |
---|
| 808 | +} |
---|
| 809 | + |
---|
743 | 810 | #ifdef CONFIG_ROCKCHIP_MPP_PROC_FS |
---|
744 | 811 | struct proc_dir_entry * |
---|
745 | 812 | mpp_procfs_create_u32(const char *name, umode_t mode, |
---|
746 | 813 | struct proc_dir_entry *parent, void *data); |
---|
| 814 | +void mpp_procfs_create_common(struct proc_dir_entry *parent, struct mpp_dev *mpp); |
---|
747 | 815 | #else |
---|
748 | 816 | static inline struct proc_dir_entry * |
---|
749 | 817 | mpp_procfs_create_u32(const char *name, umode_t mode, |
---|
.. | .. |
---|
751 | 819 | { |
---|
752 | 820 | return 0; |
---|
753 | 821 | } |
---|
| 822 | +void mpp_procfs_create_common(struct proc_dir_entry *parent, struct mpp_dev *mpp) |
---|
| 823 | +{ |
---|
| 824 | +} |
---|
754 | 825 | #endif |
---|
755 | 826 | |
---|
756 | 827 | #ifdef CONFIG_ROCKCHIP_MPP_PROC_FS |
---|