| .. | .. |
|---|
| 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 |
|---|