| .. | .. |
|---|
| 60 | 60 | /* interrupt read back in table buffer */ |
|---|
| 61 | 61 | u32 tb_reg_int; |
|---|
| 62 | 62 | bool hack_setup; |
|---|
| 63 | + u32 tb_reg_cycle; |
|---|
| 64 | + u32 tb_reg_out; |
|---|
| 65 | + u32 tb_reg_ref_s; |
|---|
| 66 | + u32 tb_reg_ref_e; |
|---|
| 63 | 67 | struct rkvdec_link_status reg_status; |
|---|
| 64 | 68 | }; |
|---|
| 65 | 69 | |
|---|
| .. | .. |
|---|
| 113 | 117 | }, |
|---|
| 114 | 118 | .tb_reg_int = 164, |
|---|
| 115 | 119 | .hack_setup = 1, |
|---|
| 120 | + .tb_reg_cycle = 179, |
|---|
| 116 | 121 | .reg_status = { |
|---|
| 117 | 122 | .dec_num_mask = 0x3fffffff, |
|---|
| 118 | 123 | .err_flag_base = 0x010, |
|---|
| .. | .. |
|---|
| 122 | 127 | |
|---|
| 123 | 128 | /* vdpu382 link hw info */ |
|---|
| 124 | 129 | struct rkvdec_link_info rkvdec_link_v2_hw_info = { |
|---|
| 125 | | - .tb_reg_num = 218, |
|---|
| 130 | + .tb_reg_num = 222, |
|---|
| 126 | 131 | .tb_reg_next = 0, |
|---|
| 127 | 132 | .tb_reg_r = 1, |
|---|
| 128 | 133 | .tb_reg_second_en = 8, |
|---|
| .. | .. |
|---|
| 162 | 167 | .part_r[0] = { |
|---|
| 163 | 168 | .tb_reg_off = 180, |
|---|
| 164 | 169 | .reg_start = 224, |
|---|
| 165 | | - .reg_num = 10, |
|---|
| 170 | + .reg_num = 12, |
|---|
| 166 | 171 | }, |
|---|
| 167 | 172 | .part_r[1] = { |
|---|
| 168 | | - .tb_reg_off = 190, |
|---|
| 173 | + .tb_reg_off = 192, |
|---|
| 169 | 174 | .reg_start = 258, |
|---|
| 170 | | - .reg_num = 28, |
|---|
| 175 | + .reg_num = 30, |
|---|
| 171 | 176 | }, |
|---|
| 172 | | - .tb_reg_int = 180, |
|---|
| 173 | | - .hack_setup = 0, |
|---|
| 177 | + .tb_reg_int = 180, |
|---|
| 178 | + .hack_setup = 0, |
|---|
| 179 | + .tb_reg_cycle = 197, |
|---|
| 180 | + .tb_reg_out = 86, |
|---|
| 181 | + .tb_reg_ref_s = 104, |
|---|
| 182 | + .tb_reg_ref_e = 119, |
|---|
| 174 | 183 | .reg_status = { |
|---|
| 175 | 184 | .dec_num_mask = 0x000fffff, |
|---|
| 176 | 185 | .err_flag_base = 0x024, |
|---|
| 177 | 186 | .err_flag_bit = BIT(8), |
|---|
| 178 | 187 | }, |
|---|
| 179 | 188 | }; |
|---|
| 189 | + |
|---|
| 190 | +static void rkvdec2_link_free_task(struct kref *ref); |
|---|
| 180 | 191 | |
|---|
| 181 | 192 | static void rkvdec_link_status_update(struct rkvdec_link_dev *dev) |
|---|
| 182 | 193 | { |
|---|
| .. | .. |
|---|
| 426 | 437 | memcpy(&tb_reg[off], &task->reg[s], n * sizeof(u32)); |
|---|
| 427 | 438 | } |
|---|
| 428 | 439 | |
|---|
| 429 | | - /* setup error mode flag */ |
|---|
| 430 | | - tb_reg[9] |= BIT(18) | BIT(9); |
|---|
| 431 | 440 | tb_reg[info->tb_reg_second_en] |= RKVDEC_WAIT_RESET_EN; |
|---|
| 432 | 441 | |
|---|
| 433 | 442 | /* memset read registers */ |
|---|
| .. | .. |
|---|
| 514 | 523 | } |
|---|
| 515 | 524 | |
|---|
| 516 | 525 | if (!resend) { |
|---|
| 526 | + u32 timing_en = dev->mpp->srv->timing_en; |
|---|
| 517 | 527 | u32 i; |
|---|
| 518 | 528 | |
|---|
| 519 | 529 | for (i = 0; i < task_to_run; i++) { |
|---|
| .. | .. |
|---|
| 523 | 533 | if (!task_ddr) |
|---|
| 524 | 534 | continue; |
|---|
| 525 | 535 | |
|---|
| 526 | | - set_bit(TASK_STATE_START, &task_ddr->state); |
|---|
| 527 | | - schedule_delayed_work(&task_ddr->timeout_work, |
|---|
| 528 | | - msecs_to_jiffies(200)); |
|---|
| 529 | | - mpp_time_record(task_ddr); |
|---|
| 536 | + mpp_task_run_begin(task_ddr, timing_en, MPP_WORK_TIMEOUT_DELAY); |
|---|
| 537 | + mpp_task_run_end(task_ddr, timing_en); |
|---|
| 530 | 538 | } |
|---|
| 531 | 539 | } else { |
|---|
| 532 | 540 | if (task_total) |
|---|
| .. | .. |
|---|
| 538 | 546 | |
|---|
| 539 | 547 | /* start config before all registers are set */ |
|---|
| 540 | 548 | wmb(); |
|---|
| 549 | + |
|---|
| 550 | + mpp_iommu_flush_tlb(dev->mpp->iommu_info); |
|---|
| 541 | 551 | |
|---|
| 542 | 552 | /* configure done */ |
|---|
| 543 | 553 | writel(RKVDEC_LINK_BIT_CFG_DONE, reg_base + RKVDEC_LINK_CFG_CTRL_BASE); |
|---|
| .. | .. |
|---|
| 591 | 601 | struct rkvdec_link_info *info = link_dec->info; |
|---|
| 592 | 602 | u32 *table_base = (u32 *)link_dec->table->vaddr; |
|---|
| 593 | 603 | int i; |
|---|
| 604 | + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); |
|---|
| 594 | 605 | |
|---|
| 595 | 606 | for (i = 0; i < count; i++) { |
|---|
| 596 | 607 | int idx = rkvdec_link_get_task_read(link_dec); |
|---|
| .. | .. |
|---|
| 599 | 610 | u32 *regs = NULL; |
|---|
| 600 | 611 | u32 irq_status = 0; |
|---|
| 601 | 612 | |
|---|
| 602 | | - if (!mpp_task) { |
|---|
| 613 | + if (!mpp_task && info->hack_setup) { |
|---|
| 603 | 614 | regs = table_base + idx * link_dec->link_reg_count; |
|---|
| 604 | 615 | mpp_dbg_link_flow("slot %d read task stuff\n", idx); |
|---|
| 605 | 616 | |
|---|
| 606 | 617 | link_dec->stuff_total++; |
|---|
| 607 | 618 | if (link_dec->statistic_count && |
|---|
| 608 | | - regs[RKVDEC_LINK_REG_CYCLE_CNT]) { |
|---|
| 619 | + regs[info->tb_reg_cycle]) { |
|---|
| 609 | 620 | link_dec->stuff_cycle_sum += |
|---|
| 610 | | - regs[RKVDEC_LINK_REG_CYCLE_CNT]; |
|---|
| 621 | + regs[info->tb_reg_cycle]; |
|---|
| 611 | 622 | link_dec->stuff_cnt++; |
|---|
| 612 | 623 | if (link_dec->stuff_cnt >= |
|---|
| 613 | 624 | link_dec->statistic_count) { |
|---|
| .. | .. |
|---|
| 648 | 659 | continue; |
|---|
| 649 | 660 | } |
|---|
| 650 | 661 | |
|---|
| 651 | | - mpp_time_diff(mpp_task); |
|---|
| 662 | + if (!mpp_task) |
|---|
| 663 | + return 0; |
|---|
| 664 | + |
|---|
| 652 | 665 | task = to_rkvdec2_task(mpp_task); |
|---|
| 653 | 666 | regs = table_base + idx * link_dec->link_reg_count; |
|---|
| 667 | + link_dec->error_iova = regs[info->tb_reg_out]; |
|---|
| 654 | 668 | irq_status = regs[info->tb_reg_int]; |
|---|
| 669 | + mpp_task->hw_cycles = regs[info->tb_reg_cycle]; |
|---|
| 670 | + mpp_time_diff_with_hw_time(mpp_task, dec->aclk_info.real_rate_hz); |
|---|
| 655 | 671 | mpp_dbg_link_flow("slot %d rd task %d\n", idx, |
|---|
| 656 | 672 | mpp_task->task_index); |
|---|
| 657 | 673 | |
|---|
| 658 | 674 | task->irq_status = irq_status ? irq_status : mpp->irq_status; |
|---|
| 659 | | - |
|---|
| 675 | + mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", task->irq_status); |
|---|
| 660 | 676 | cancel_delayed_work_sync(&mpp_task->timeout_work); |
|---|
| 661 | 677 | set_bit(TASK_STATE_HANDLE, &mpp_task->state); |
|---|
| 662 | 678 | |
|---|
| 663 | 679 | if (link_dec->statistic_count && |
|---|
| 664 | | - regs[RKVDEC_LINK_REG_CYCLE_CNT]) { |
|---|
| 680 | + regs[info->tb_reg_cycle]) { |
|---|
| 665 | 681 | link_dec->task_cycle_sum += |
|---|
| 666 | | - regs[RKVDEC_LINK_REG_CYCLE_CNT]; |
|---|
| 682 | + regs[info->tb_reg_cycle]; |
|---|
| 667 | 683 | link_dec->task_cnt++; |
|---|
| 668 | 684 | if (link_dec->task_cnt >= link_dec->statistic_count) { |
|---|
| 669 | 685 | dev_info(link_dec->dev, "hw cycle %u\n", |
|---|
| .. | .. |
|---|
| 691 | 707 | set_bit(TASK_STATE_PROC_DONE, &mpp_task->state); |
|---|
| 692 | 708 | /* Wake up the GET thread */ |
|---|
| 693 | 709 | wake_up(&task->wait); |
|---|
| 710 | + kref_put(&mpp_task->ref, rkvdec2_link_free_task); |
|---|
| 711 | + link_dec->tasks_hw[idx] = NULL; |
|---|
| 694 | 712 | } |
|---|
| 695 | 713 | |
|---|
| 696 | 714 | return 0; |
|---|
| .. | .. |
|---|
| 729 | 747 | |
|---|
| 730 | 748 | static int rkvdec2_link_reset(struct mpp_dev *mpp) |
|---|
| 731 | 749 | { |
|---|
| 732 | | - struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); |
|---|
| 733 | 750 | |
|---|
| 734 | 751 | dev_info(mpp->dev, "resetting...\n"); |
|---|
| 735 | 752 | |
|---|
| .. | .. |
|---|
| 740 | 757 | |
|---|
| 741 | 758 | rockchip_save_qos(mpp->dev); |
|---|
| 742 | 759 | |
|---|
| 743 | | - mutex_lock(&dec->sip_reset_lock); |
|---|
| 744 | | - rockchip_dmcfreq_lock(); |
|---|
| 745 | | - sip_smc_vpu_reset(0, 0, 0); |
|---|
| 746 | | - rockchip_dmcfreq_unlock(); |
|---|
| 747 | | - mutex_unlock(&dec->sip_reset_lock); |
|---|
| 760 | + if (mpp->hw_ops->reset) |
|---|
| 761 | + mpp->hw_ops->reset(mpp); |
|---|
| 748 | 762 | |
|---|
| 749 | 763 | rockchip_restore_qos(mpp->dev); |
|---|
| 750 | 764 | |
|---|
| .. | .. |
|---|
| 762 | 776 | return 0; |
|---|
| 763 | 777 | } |
|---|
| 764 | 778 | |
|---|
| 779 | +static void rkvdec2_check_err_ref(struct mpp_dev *mpp) |
|---|
| 780 | +{ |
|---|
| 781 | + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); |
|---|
| 782 | + struct rkvdec_link_dev *link_dec = dec->link_dec; |
|---|
| 783 | + struct rkvdec_link_info *link_info = link_dec->info; |
|---|
| 784 | + struct mpp_taskqueue *queue = mpp->queue; |
|---|
| 785 | + struct mpp_task *mpp_task = NULL, *n; |
|---|
| 786 | + struct rkvdec2_task *task; |
|---|
| 787 | + int i; |
|---|
| 788 | + |
|---|
| 789 | + if (!link_dec->error_iova || !dec->err_ref_hack) |
|---|
| 790 | + return; |
|---|
| 791 | + |
|---|
| 792 | + dev_err(mpp->dev, "err task iova %#08x\n", link_dec->error_iova); |
|---|
| 793 | + list_for_each_entry_safe(mpp_task, n, &queue->running_list, queue_link) { |
|---|
| 794 | + if (mpp_task) { |
|---|
| 795 | + u32 *regs = NULL; |
|---|
| 796 | + u32 *table_base = (u32 *)link_dec->table->vaddr; |
|---|
| 797 | + |
|---|
| 798 | + task = to_rkvdec2_task(mpp_task); |
|---|
| 799 | + regs = table_base + task->slot_idx * link_dec->link_reg_count; |
|---|
| 800 | + |
|---|
| 801 | + for (i = link_info->tb_reg_ref_s; i <= link_info->tb_reg_ref_e; i++) { |
|---|
| 802 | + if (regs[i] == link_dec->error_iova) |
|---|
| 803 | + regs[i] = 0; |
|---|
| 804 | + } |
|---|
| 805 | + } |
|---|
| 806 | + } |
|---|
| 807 | + |
|---|
| 808 | + mutex_lock(&queue->pending_lock); |
|---|
| 809 | + list_for_each_entry_safe(mpp_task, n, &queue->pending_list, queue_link) { |
|---|
| 810 | + task = to_rkvdec2_task(mpp_task); |
|---|
| 811 | + |
|---|
| 812 | + /* ref frame reg index start - end */ |
|---|
| 813 | + for (i = 164; i <= 179; i++) { |
|---|
| 814 | + if (task->reg[i] == link_dec->error_iova) |
|---|
| 815 | + task->reg[i] = 0; |
|---|
| 816 | + } |
|---|
| 817 | + } |
|---|
| 818 | + mutex_unlock(&queue->pending_lock); |
|---|
| 819 | + link_dec->error_iova = 0; |
|---|
| 820 | +} |
|---|
| 821 | + |
|---|
| 765 | 822 | static int rkvdec2_link_irq(struct mpp_dev *mpp) |
|---|
| 766 | 823 | { |
|---|
| 767 | 824 | struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); |
|---|
| .. | .. |
|---|
| 774 | 831 | } |
|---|
| 775 | 832 | |
|---|
| 776 | 833 | irq_status = readl(link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); |
|---|
| 777 | | - |
|---|
| 778 | | - mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", irq_status); |
|---|
| 779 | | - mpp_dbg_link_flow("link irq %08x\n", irq_status); |
|---|
| 780 | 834 | |
|---|
| 781 | 835 | if (irq_status & RKVDEC_LINK_BIT_IRQ_RAW) { |
|---|
| 782 | 836 | u32 enabled = readl(link_dec->reg_base + RKVDEC_LINK_EN_BASE); |
|---|
| .. | .. |
|---|
| 795 | 849 | |
|---|
| 796 | 850 | writel_relaxed(0, link_dec->reg_base + RKVDEC_LINK_IRQ_BASE); |
|---|
| 797 | 851 | } |
|---|
| 798 | | - |
|---|
| 852 | + mpp_debug((DEBUG_IRQ_STATUS | DEBUG_LINK_TABLE), "irq_status: %08x : %08x\n", |
|---|
| 853 | + irq_status, mpp->irq_status); |
|---|
| 799 | 854 | return 0; |
|---|
| 800 | 855 | } |
|---|
| 801 | 856 | |
|---|
| .. | .. |
|---|
| 815 | 870 | mpp_debug_enter(); |
|---|
| 816 | 871 | |
|---|
| 817 | 872 | disable_irq(mpp->irq); |
|---|
| 873 | + mpp_iommu_disable_irq(mpp->iommu_info); |
|---|
| 818 | 874 | rkvdec_link_status_update(link_dec); |
|---|
| 819 | 875 | link_dec->irq_status = irq_status; |
|---|
| 820 | 876 | prev_dec_num = link_dec->task_decoded; |
|---|
| .. | .. |
|---|
| 822 | 878 | if (!link_dec->enabled || task_timeout) { |
|---|
| 823 | 879 | u32 val; |
|---|
| 824 | 880 | |
|---|
| 825 | | - if (task_timeout) |
|---|
| 881 | + if (task_timeout) { |
|---|
| 826 | 882 | rkvdec_link_reg_dump("timeout", link_dec); |
|---|
| 883 | + link_dec->decoded += task_timeout; |
|---|
| 884 | + } |
|---|
| 827 | 885 | |
|---|
| 828 | 886 | val = mpp_read(mpp, 224 * 4); |
|---|
| 829 | 887 | if (link_info->hack_setup && !(val & BIT(2))) { |
|---|
| .. | .. |
|---|
| 838 | 896 | if (link_dec->enabled && !count && !need_reset) { |
|---|
| 839 | 897 | /* process extra isr when task is processed */ |
|---|
| 840 | 898 | enable_irq(mpp->irq); |
|---|
| 899 | + mpp_iommu_enable_irq(mpp->iommu_info); |
|---|
| 841 | 900 | goto done; |
|---|
| 842 | 901 | } |
|---|
| 843 | 902 | |
|---|
| .. | .. |
|---|
| 851 | 910 | goto do_reset; |
|---|
| 852 | 911 | |
|---|
| 853 | 912 | enable_irq(mpp->irq); |
|---|
| 913 | + mpp_iommu_enable_irq(mpp->iommu_info); |
|---|
| 854 | 914 | goto done; |
|---|
| 855 | 915 | |
|---|
| 856 | 916 | do_reset: |
|---|
| 917 | + rkvdec2_check_err_ref(mpp); |
|---|
| 857 | 918 | /* NOTE: irq may run with reset */ |
|---|
| 858 | 919 | atomic_inc(&mpp->reset_request); |
|---|
| 859 | 920 | rkvdec2_link_reset(mpp); |
|---|
| 860 | 921 | link_dec->task_decoded = 0; |
|---|
| 861 | 922 | link_dec->task_total = 0; |
|---|
| 862 | 923 | enable_irq(mpp->irq); |
|---|
| 924 | + mpp_iommu_enable_irq(mpp->iommu_info); |
|---|
| 863 | 925 | |
|---|
| 864 | 926 | if (link_dec->total == link_dec->decoded) |
|---|
| 865 | 927 | goto done; |
|---|
| .. | .. |
|---|
| 881 | 943 | mpp_debug_leave(); |
|---|
| 882 | 944 | |
|---|
| 883 | 945 | return IRQ_HANDLED; |
|---|
| 946 | +} |
|---|
| 947 | + |
|---|
| 948 | +static int rkvdec2_link_iommu_handle(struct iommu_domain *iommu, |
|---|
| 949 | + struct device *iommu_dev, |
|---|
| 950 | + unsigned long iova, |
|---|
| 951 | + int status, void *arg) |
|---|
| 952 | +{ |
|---|
| 953 | + struct mpp_dev *mpp = (struct mpp_dev *)arg; |
|---|
| 954 | + |
|---|
| 955 | + dev_err(iommu_dev, "fault addr 0x%08lx status %x arg %p\n", |
|---|
| 956 | + iova, status, arg); |
|---|
| 957 | + |
|---|
| 958 | + if (!mpp) { |
|---|
| 959 | + dev_err(iommu_dev, "pagefault without device to handle\n"); |
|---|
| 960 | + return 0; |
|---|
| 961 | + } |
|---|
| 962 | + |
|---|
| 963 | + rk_iommu_mask_irq(mpp->dev); |
|---|
| 964 | + |
|---|
| 965 | + return 0; |
|---|
| 884 | 966 | } |
|---|
| 885 | 967 | |
|---|
| 886 | 968 | int rkvdec2_link_remove(struct mpp_dev *mpp, struct rkvdec_link_dev *link_dec) |
|---|
| .. | .. |
|---|
| 1016 | 1098 | |
|---|
| 1017 | 1099 | if (link_dec->info->hack_setup) |
|---|
| 1018 | 1100 | rkvdec2_link_hack_data_setup(dec->fix); |
|---|
| 1019 | | - |
|---|
| 1101 | + iommu_set_fault_handler(mpp->iommu_info->domain, |
|---|
| 1102 | + rkvdec2_link_iommu_handle, mpp); |
|---|
| 1020 | 1103 | link_dec->mpp = mpp; |
|---|
| 1021 | 1104 | link_dec->dev = dev; |
|---|
| 1022 | 1105 | atomic_set(&link_dec->task_timeout, 0); |
|---|
| .. | .. |
|---|
| 1060 | 1143 | } |
|---|
| 1061 | 1144 | session = task->session; |
|---|
| 1062 | 1145 | |
|---|
| 1063 | | - mpp_debug_func(DEBUG_TASK_INFO, "task %d:%d state 0x%lx\n", |
|---|
| 1064 | | - session->index, task->task_index, task->state); |
|---|
| 1146 | + mpp_debug_func(DEBUG_TASK_INFO, |
|---|
| 1147 | + "session %d:%d task %d state 0x%lx abort_request %d\n", |
|---|
| 1148 | + session->device_type, session->index, task->task_index, |
|---|
| 1149 | + task->state, atomic_read(&task->abort_request)); |
|---|
| 1065 | 1150 | if (!session->mpp) { |
|---|
| 1066 | 1151 | mpp_err("session %d session->mpp is null.\n", session->index); |
|---|
| 1067 | 1152 | return; |
|---|
| .. | .. |
|---|
| 1112 | 1197 | |
|---|
| 1113 | 1198 | if (!link_dec->irq_enabled) { |
|---|
| 1114 | 1199 | enable_irq(mpp->irq); |
|---|
| 1200 | + mpp_iommu_enable_irq(mpp->iommu_info); |
|---|
| 1115 | 1201 | link_dec->irq_enabled = 1; |
|---|
| 1116 | 1202 | } |
|---|
| 1117 | 1203 | |
|---|
| .. | .. |
|---|
| 1146 | 1232 | |
|---|
| 1147 | 1233 | if (atomic_xchg(&link_dec->power_enabled, 0)) { |
|---|
| 1148 | 1234 | disable_irq(mpp->irq); |
|---|
| 1235 | + mpp_iommu_disable_irq(mpp->iommu_info); |
|---|
| 1149 | 1236 | link_dec->irq_enabled = 0; |
|---|
| 1150 | 1237 | |
|---|
| 1151 | 1238 | if (mpp->hw_ops->clk_off) |
|---|
| .. | .. |
|---|
| 1287 | 1374 | u32 task_to_run = 0; |
|---|
| 1288 | 1375 | int slot_idx = 0; |
|---|
| 1289 | 1376 | int ret; |
|---|
| 1377 | + struct mpp_session *session = task->session; |
|---|
| 1290 | 1378 | |
|---|
| 1291 | 1379 | mpp_debug_enter(); |
|---|
| 1292 | 1380 | |
|---|
| .. | .. |
|---|
| 1301 | 1389 | } |
|---|
| 1302 | 1390 | |
|---|
| 1303 | 1391 | rkvdec2_link_power_on(mpp); |
|---|
| 1304 | | - mpp_debug(DEBUG_TASK_INFO, "pid %d, start hw %s\n", |
|---|
| 1305 | | - task->session->pid, dev_name(mpp->dev)); |
|---|
| 1392 | + mpp_debug_func(DEBUG_TASK_INFO, |
|---|
| 1393 | + "%s session %d:%d task=%d state=0x%lx\n", |
|---|
| 1394 | + dev_name(mpp->dev), session->device_type, |
|---|
| 1395 | + session->index, task->task_index, task->state); |
|---|
| 1306 | 1396 | |
|---|
| 1307 | 1397 | /* prepare the task for running */ |
|---|
| 1308 | 1398 | if (test_and_set_bit(TASK_STATE_PREPARE, &task->state)) |
|---|
| .. | .. |
|---|
| 1372 | 1462 | struct mpp_task *task) |
|---|
| 1373 | 1463 | { |
|---|
| 1374 | 1464 | set_bit(TASK_STATE_DONE, &task->state); |
|---|
| 1375 | | - kref_put(&task->ref, rkvdec2_link_free_task); |
|---|
| 1376 | 1465 | |
|---|
| 1377 | 1466 | return 0; |
|---|
| 1378 | 1467 | } |
|---|
| .. | .. |
|---|
| 1479 | 1568 | goto done; |
|---|
| 1480 | 1569 | |
|---|
| 1481 | 1570 | disable_irq(mpp->irq); |
|---|
| 1571 | + mpp_iommu_disable_irq(mpp->iommu_info); |
|---|
| 1482 | 1572 | rkvdec2_link_reset(mpp); |
|---|
| 1483 | 1573 | link_dec->task_decoded = 0; |
|---|
| 1484 | 1574 | link_dec->task_total = 0; |
|---|
| 1485 | 1575 | enable_irq(mpp->irq); |
|---|
| 1576 | + mpp_iommu_enable_irq(mpp->iommu_info); |
|---|
| 1486 | 1577 | } |
|---|
| 1487 | 1578 | /* |
|---|
| 1488 | 1579 | * process pending queue to find the task to accept. |
|---|
| .. | .. |
|---|
| 1500 | 1591 | mutex_lock(&queue->pending_lock); |
|---|
| 1501 | 1592 | list_del_init(&task->queue_link); |
|---|
| 1502 | 1593 | |
|---|
| 1503 | | - kref_get(&task->ref); |
|---|
| 1504 | 1594 | set_bit(TASK_STATE_ABORT_READY, &task->state); |
|---|
| 1505 | 1595 | set_bit(TASK_STATE_PROC_DONE, &task->state); |
|---|
| 1506 | 1596 | |
|---|
| .. | .. |
|---|
| 1546 | 1636 | rkvdec2_link_power_off(mpp); |
|---|
| 1547 | 1637 | } |
|---|
| 1548 | 1638 | |
|---|
| 1549 | | - mutex_lock(&queue->session_lock); |
|---|
| 1550 | | - while (queue->detach_count) { |
|---|
| 1551 | | - struct mpp_session *session = NULL; |
|---|
| 1552 | | - |
|---|
| 1553 | | - session = list_first_entry_or_null(&queue->session_detach, struct mpp_session, |
|---|
| 1554 | | - session_link); |
|---|
| 1555 | | - if (session) { |
|---|
| 1556 | | - list_del_init(&session->session_link); |
|---|
| 1557 | | - queue->detach_count--; |
|---|
| 1558 | | - } |
|---|
| 1559 | | - |
|---|
| 1560 | | - mutex_unlock(&queue->session_lock); |
|---|
| 1561 | | - |
|---|
| 1562 | | - if (session) { |
|---|
| 1563 | | - mpp_dbg_session("%s detach count %d\n", dev_name(mpp->dev), |
|---|
| 1564 | | - queue->detach_count); |
|---|
| 1565 | | - mpp_session_deinit(session); |
|---|
| 1566 | | - } |
|---|
| 1567 | | - |
|---|
| 1568 | | - mutex_lock(&queue->session_lock); |
|---|
| 1569 | | - } |
|---|
| 1570 | | - mutex_unlock(&queue->session_lock); |
|---|
| 1639 | + mpp_session_cleanup_detach(queue, work_s); |
|---|
| 1571 | 1640 | } |
|---|
| 1572 | 1641 | |
|---|
| 1573 | 1642 | void rkvdec2_link_session_deinit(struct mpp_session *session) |
|---|
| .. | .. |
|---|
| 1580 | 1649 | |
|---|
| 1581 | 1650 | if (session->dma) { |
|---|
| 1582 | 1651 | mpp_dbg_session("session %d destroy dma\n", session->index); |
|---|
| 1583 | | - mpp_iommu_down_read(mpp->iommu_info); |
|---|
| 1652 | + mpp_iommu_down_write(mpp->iommu_info); |
|---|
| 1584 | 1653 | mpp_dma_session_destroy(session->dma); |
|---|
| 1585 | | - mpp_iommu_up_read(mpp->iommu_info); |
|---|
| 1654 | + mpp_iommu_up_write(mpp->iommu_info); |
|---|
| 1586 | 1655 | session->dma = NULL; |
|---|
| 1587 | 1656 | } |
|---|
| 1588 | 1657 | if (session->srv) { |
|---|