.. | .. |
---|
266 | 266 | |
---|
267 | 267 | mem_region = mpp_task_attach_fd(&task->mpp_task, usr_fd); |
---|
268 | 268 | if (IS_ERR(mem_region)) { |
---|
269 | | - mpp_debug(DEBUG_IOMMU, "reg[%3d]: %08x failed\n", |
---|
270 | | - iep2_addr_rnum[i], paddr[i]); |
---|
| 269 | + mpp_err("reg[%03d]: %08x failed\n", |
---|
| 270 | + iep2_addr_rnum[i], paddr[i]); |
---|
271 | 271 | return PTR_ERR(mem_region); |
---|
272 | 272 | } |
---|
273 | 273 | |
---|
.. | .. |
---|
389 | 389 | | IEP2_REG_DIL_OSD_EN |
---|
390 | 390 | | IEP2_REG_DIL_PD_EN |
---|
391 | 391 | | IEP2_REG_DIL_FF_EN |
---|
392 | | - | IEP2_REG_DIL_MD_PRE_EN |
---|
393 | 392 | | IEP2_REG_DIL_FIELD_ORDER(cfg->dil_field_order) |
---|
394 | 393 | | IEP2_REG_DIL_OUT_MODE(cfg->dil_out_mode) |
---|
395 | 394 | | IEP2_REG_DIL_MODE(cfg->dil_mode); |
---|
396 | 395 | if (cfg->roi_en) |
---|
397 | 396 | reg |= IEP2_REG_DIL_ROI_EN; |
---|
| 397 | + if (cfg->md_lambda < 8) |
---|
| 398 | + reg |= IEP2_REG_DIL_MD_PRE_EN; |
---|
398 | 399 | mpp_write_relaxed(mpp, IEP2_REG_DIL_CONFIG0, reg); |
---|
399 | 400 | |
---|
400 | 401 | if (cfg->dil_mode != ROCKCHIP_IEP2_DIL_MODE_PD) { |
---|
.. | .. |
---|
437 | 438 | mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_NXTUV, bot->cbcr); |
---|
438 | 439 | mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_NXTV, bot->cr); |
---|
439 | 440 | } |
---|
| 441 | + |
---|
| 442 | + reg = IEP2_REG_TIMEOUT_CFG_EN | 0x3ffffff; |
---|
| 443 | + mpp_write_relaxed(mpp, IEP2_REG_TIMEOUT_CFG, reg); |
---|
440 | 444 | |
---|
441 | 445 | mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_PREY, cfg->src[2].y); |
---|
442 | 446 | mpp_write_relaxed(mpp, IEP2_REG_SRC_ADDR_PREUV, cfg->src[2].cbcr); |
---|
.. | .. |
---|
580 | 584 | struct mpp_task *mpp_task) |
---|
581 | 585 | { |
---|
582 | 586 | struct iep_task *task = NULL; |
---|
| 587 | + u32 timing_en = mpp->srv->timing_en; |
---|
583 | 588 | |
---|
584 | 589 | mpp_debug_enter(); |
---|
585 | 590 | |
---|
.. | .. |
---|
598 | 603 | mpp_write_relaxed(mpp, IEP2_REG_INT_EN, |
---|
599 | 604 | IEP2_REG_FRM_DONE_EN |
---|
600 | 605 | | IEP2_REG_OSD_MAX_EN |
---|
601 | | - | IEP2_REG_BUS_ERROR_EN); |
---|
| 606 | + | IEP2_REG_BUS_ERROR_EN |
---|
| 607 | + | IEP2_REG_TIMEOUT_EN); |
---|
| 608 | + |
---|
| 609 | + /* flush tlb before starting hardware */ |
---|
| 610 | + mpp_iommu_flush_tlb(mpp->iommu_info); |
---|
| 611 | + |
---|
| 612 | + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); |
---|
602 | 613 | |
---|
603 | 614 | /* Last, flush the registers */ |
---|
604 | 615 | wmb(); |
---|
605 | 616 | /* start iep2 */ |
---|
606 | 617 | mpp_write(mpp, IEP2_REG_FRM_START, 1); |
---|
| 618 | + |
---|
| 619 | + mpp_task_run_end(mpp_task, timing_en); |
---|
607 | 620 | |
---|
608 | 621 | mpp_debug_leave(); |
---|
609 | 622 | |
---|
.. | .. |
---|
612 | 625 | |
---|
613 | 626 | static int iep2_irq(struct mpp_dev *mpp) |
---|
614 | 627 | { |
---|
| 628 | + u32 work_mode = mpp_read(mpp, IEP2_REG_WORK_MODE); |
---|
| 629 | + |
---|
| 630 | + if (work_mode && !(work_mode & IEP2_REG_IEP2_MODE)) |
---|
| 631 | + return IRQ_NONE; |
---|
615 | 632 | mpp->irq_status = mpp_read(mpp, IEP2_REG_INT_STS); |
---|
616 | 633 | mpp_write(mpp, IEP2_REG_INT_CLR, 0xffffffff); |
---|
617 | 634 | |
---|
.. | .. |
---|
640 | 657 | mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", |
---|
641 | 658 | task->irq_status); |
---|
642 | 659 | |
---|
643 | | - if (IEP2_REG_RO_BUS_ERROR_STS(task->irq_status)) |
---|
| 660 | + if (IEP2_REG_RO_BUS_ERROR_STS(task->irq_status) || |
---|
| 661 | + IEP2_REG_RO_TIMEOUT_STS(task->irq_status)) |
---|
644 | 662 | atomic_inc(&mpp->reset_request); |
---|
645 | 663 | |
---|
646 | 664 | mpp_task_finish(mpp_task->session, mpp_task); |
---|
.. | .. |
---|
769 | 787 | iep->procfs = NULL; |
---|
770 | 788 | return -EIO; |
---|
771 | 789 | } |
---|
| 790 | + |
---|
| 791 | + /* for common mpp_dev options */ |
---|
| 792 | + mpp_procfs_create_common(iep->procfs, mpp); |
---|
| 793 | + |
---|
772 | 794 | mpp_procfs_create_u32("aclk", 0644, |
---|
773 | 795 | iep->procfs, &iep->aclk_info.debug_rate_hz); |
---|
774 | 796 | mpp_procfs_create_u32("session_buffers", 0644, |
---|
.. | .. |
---|
870 | 892 | { |
---|
871 | 893 | struct iep2_dev *iep = to_iep2_dev(mpp); |
---|
872 | 894 | |
---|
873 | | - if (iep->rst_a && iep->rst_h && iep->rst_s) { |
---|
874 | | - /* Don't skip this or iommu won't work after reset */ |
---|
875 | | - rockchip_pmu_idle_request(mpp->dev, true); |
---|
876 | | - mpp_safe_reset(iep->rst_a); |
---|
877 | | - mpp_safe_reset(iep->rst_h); |
---|
878 | | - mpp_safe_reset(iep->rst_s); |
---|
879 | | - udelay(5); |
---|
880 | | - mpp_safe_unreset(iep->rst_a); |
---|
881 | | - mpp_safe_unreset(iep->rst_h); |
---|
882 | | - mpp_safe_unreset(iep->rst_s); |
---|
883 | | - rockchip_pmu_idle_request(mpp->dev, false); |
---|
| 895 | + int ret = 0; |
---|
| 896 | + u32 rst_status = 0; |
---|
| 897 | + |
---|
| 898 | + /* soft rest first */ |
---|
| 899 | + mpp_write(mpp, IEP2_REG_IEP_CONFIG0, IEP2_REG_ACLK_SRESET_P); |
---|
| 900 | + ret = readl_relaxed_poll_timeout(mpp->reg_base + IEP2_REG_STATUS, |
---|
| 901 | + rst_status, |
---|
| 902 | + rst_status & IEP2_REG_ARST_FINISH_DONE, |
---|
| 903 | + 0, 5); |
---|
| 904 | + if (ret) { |
---|
| 905 | + mpp_err("soft reset timeout, use cru reset\n"); |
---|
| 906 | + if (iep->rst_a && iep->rst_h && iep->rst_s) { |
---|
| 907 | + /* Don't skip this or iommu won't work after reset */ |
---|
| 908 | + mpp_pmu_idle_request(mpp, true); |
---|
| 909 | + mpp_safe_reset(iep->rst_a); |
---|
| 910 | + mpp_safe_reset(iep->rst_h); |
---|
| 911 | + mpp_safe_reset(iep->rst_s); |
---|
| 912 | + udelay(5); |
---|
| 913 | + mpp_safe_unreset(iep->rst_a); |
---|
| 914 | + mpp_safe_unreset(iep->rst_h); |
---|
| 915 | + mpp_safe_unreset(iep->rst_s); |
---|
| 916 | + mpp_pmu_idle_request(mpp, false); |
---|
| 917 | + } |
---|
884 | 918 | } |
---|
885 | 919 | |
---|
886 | 920 | return 0; |
---|
.. | .. |
---|
943 | 977 | return -ENOMEM; |
---|
944 | 978 | |
---|
945 | 979 | mpp = &iep->mpp; |
---|
946 | | - platform_set_drvdata(pdev, iep); |
---|
| 980 | + platform_set_drvdata(pdev, mpp); |
---|
947 | 981 | |
---|
948 | 982 | if (pdev->dev.of_node) { |
---|
949 | 983 | match = of_match_node(mpp_iep2_match, pdev->dev.of_node); |
---|
.. | .. |
---|
979 | 1013 | static int iep2_remove(struct platform_device *pdev) |
---|
980 | 1014 | { |
---|
981 | 1015 | struct device *dev = &pdev->dev; |
---|
982 | | - struct iep2_dev *iep = platform_get_drvdata(pdev); |
---|
| 1016 | + struct mpp_dev *mpp = dev_get_drvdata(dev); |
---|
| 1017 | + struct iep2_dev *iep = to_iep2_dev(mpp); |
---|
983 | 1018 | |
---|
984 | 1019 | dma_free_coherent(dev, iep->roi.size, iep->roi.vaddr, iep->roi.iova); |
---|
985 | 1020 | |
---|
986 | 1021 | dev_info(dev, "remove device\n"); |
---|
987 | | - mpp_dev_remove(&iep->mpp); |
---|
988 | | - iep2_procfs_remove(&iep->mpp); |
---|
| 1022 | + mpp_dev_remove(mpp); |
---|
| 1023 | + iep2_procfs_remove(mpp); |
---|
989 | 1024 | |
---|
990 | 1025 | return 0; |
---|
991 | | -} |
---|
992 | | - |
---|
993 | | -static void iep2_shutdown(struct platform_device *pdev) |
---|
994 | | -{ |
---|
995 | | - int ret; |
---|
996 | | - int val; |
---|
997 | | - struct device *dev = &pdev->dev; |
---|
998 | | - struct iep2_dev *iep = platform_get_drvdata(pdev); |
---|
999 | | - struct mpp_dev *mpp = &iep->mpp; |
---|
1000 | | - |
---|
1001 | | - dev_info(dev, "shutdown device\n"); |
---|
1002 | | - |
---|
1003 | | - atomic_inc(&mpp->srv->shutdown_request); |
---|
1004 | | - ret = readx_poll_timeout(atomic_read, |
---|
1005 | | - &mpp->task_count, |
---|
1006 | | - val, val == 0, 20000, 200000); |
---|
1007 | | - if (ret == -ETIMEDOUT) |
---|
1008 | | - dev_err(dev, "wait total running time out\n"); |
---|
1009 | 1026 | } |
---|
1010 | 1027 | |
---|
1011 | 1028 | struct platform_driver rockchip_iep2_driver = { |
---|
1012 | 1029 | .probe = iep2_probe, |
---|
1013 | 1030 | .remove = iep2_remove, |
---|
1014 | | - .shutdown = iep2_shutdown, |
---|
| 1031 | + .shutdown = mpp_dev_shutdown, |
---|
1015 | 1032 | .driver = { |
---|
1016 | 1033 | .name = IEP2_DRIVER_NAME, |
---|
1017 | 1034 | .of_match_table = of_match_ptr(mpp_iep2_match), |
---|