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