| .. | .. |
|---|
| 36 | 36 | #include "mpp_debug.h" |
|---|
| 37 | 37 | #include "mpp_common.h" |
|---|
| 38 | 38 | #include "mpp_iommu.h" |
|---|
| 39 | +#include <soc/rockchip/rockchip_iommu.h> |
|---|
| 39 | 40 | |
|---|
| 40 | 41 | #include "hack/mpp_hack_px30.h" |
|---|
| 41 | 42 | |
|---|
| .. | .. |
|---|
| 593 | 594 | mem_region = mpp_task_attach_fd(&task->mpp_task, |
|---|
| 594 | 595 | scaling_fd); |
|---|
| 595 | 596 | if (IS_ERR(mem_region)) { |
|---|
| 597 | + mpp_err("scaling list fd %d attach failed\n", scaling_fd); |
|---|
| 596 | 598 | ret = PTR_ERR(mem_region); |
|---|
| 597 | 599 | goto done; |
|---|
| 598 | 600 | } |
|---|
| .. | .. |
|---|
| 727 | 729 | offset = task->reg[idx] >> 10 << 4; |
|---|
| 728 | 730 | } |
|---|
| 729 | 731 | mem_region = mpp_task_attach_fd(&task->mpp_task, fd); |
|---|
| 730 | | - if (IS_ERR(mem_region)) |
|---|
| 732 | + if (IS_ERR(mem_region)) { |
|---|
| 733 | + mpp_err("reg[%03d]: %08x fd %d attach failed\n", |
|---|
| 734 | + idx, task->reg[idx], fd); |
|---|
| 731 | 735 | return -EFAULT; |
|---|
| 736 | + } |
|---|
| 732 | 737 | |
|---|
| 733 | 738 | iova = mem_region->iova; |
|---|
| 734 | 739 | task->reg[idx] = iova + offset; |
|---|
| .. | .. |
|---|
| 887 | 892 | int i; |
|---|
| 888 | 893 | u32 reg_en; |
|---|
| 889 | 894 | struct rkvdec_task *task = NULL; |
|---|
| 895 | + u32 timing_en = mpp->srv->timing_en; |
|---|
| 890 | 896 | |
|---|
| 891 | 897 | mpp_debug_enter(); |
|---|
| 892 | 898 | |
|---|
| .. | .. |
|---|
| 918 | 924 | } |
|---|
| 919 | 925 | /* init current task */ |
|---|
| 920 | 926 | mpp->cur_task = mpp_task; |
|---|
| 927 | + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); |
|---|
| 921 | 928 | /* Flush the register before the start the device */ |
|---|
| 922 | 929 | wmb(); |
|---|
| 923 | 930 | mpp_write(mpp, RKVDEC_REG_INT_EN, |
|---|
| 924 | 931 | task->reg[reg_en] | RKVDEC_DEC_START); |
|---|
| 932 | + |
|---|
| 933 | + mpp_task_run_end(mpp_task, timing_en); |
|---|
| 925 | 934 | } break; |
|---|
| 926 | 935 | default: |
|---|
| 927 | 936 | break; |
|---|
| .. | .. |
|---|
| 944 | 953 | task = to_rkvdec_task(mpp_task); |
|---|
| 945 | 954 | |
|---|
| 946 | 955 | /* |
|---|
| 947 | | - * HW defeat workaround: VP9 power save optimization cause decoding |
|---|
| 956 | + * HW defeat workaround: VP9 and H.265 power save optimization cause decoding |
|---|
| 948 | 957 | * corruption, disable optimization here. |
|---|
| 949 | 958 | */ |
|---|
| 950 | 959 | fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_SYS_CTRL_INDEX]); |
|---|
| 951 | | - if (fmt == RKVDEC_FMT_VP9D) { |
|---|
| 960 | + if (fmt == RKVDEC_FMT_VP9D || fmt == RKVDEC_FMT_H265D) { |
|---|
| 952 | 961 | cfg = task->reg[RKVDEC_POWER_CTL_INDEX] | 0xFFFF; |
|---|
| 953 | 962 | task->reg[RKVDEC_POWER_CTL_INDEX] = cfg & (~(1 << 12)); |
|---|
| 954 | 963 | mpp_write_relaxed(mpp, RKVDEC_POWER_CTL_BASE, |
|---|
| .. | .. |
|---|
| 969 | 978 | if (task->link_mode == RKVDEC_MODE_ONEFRAME) |
|---|
| 970 | 979 | mpp_iommu_flush_tlb(mpp->iommu_info); |
|---|
| 971 | 980 | |
|---|
| 981 | + return rkvdec_run(mpp, mpp_task); |
|---|
| 982 | +} |
|---|
| 983 | + |
|---|
| 984 | +static int rkvdec_px30_run(struct mpp_dev *mpp, |
|---|
| 985 | + struct mpp_task *mpp_task) |
|---|
| 986 | +{ |
|---|
| 987 | + mpp_iommu_flush_tlb(mpp->iommu_info); |
|---|
| 972 | 988 | return rkvdec_run(mpp, mpp_task); |
|---|
| 973 | 989 | } |
|---|
| 974 | 990 | |
|---|
| .. | .. |
|---|
| 1171 | 1187 | dec->procfs = NULL; |
|---|
| 1172 | 1188 | return -EIO; |
|---|
| 1173 | 1189 | } |
|---|
| 1190 | + |
|---|
| 1191 | + /* for common mpp_dev options */ |
|---|
| 1192 | + mpp_procfs_create_common(dec->procfs, mpp); |
|---|
| 1193 | + |
|---|
| 1174 | 1194 | mpp_procfs_create_u32("aclk", 0644, |
|---|
| 1175 | 1195 | dec->procfs, &dec->aclk_info.debug_rate_hz); |
|---|
| 1176 | 1196 | mpp_procfs_create_u32("clk_core", 0644, |
|---|
| .. | .. |
|---|
| 1261 | 1281 | return px30_workaround_combo_init(mpp); |
|---|
| 1262 | 1282 | } |
|---|
| 1263 | 1283 | |
|---|
| 1284 | +static int rkvdec_3036_init(struct mpp_dev *mpp) |
|---|
| 1285 | +{ |
|---|
| 1286 | + rkvdec_init(mpp); |
|---|
| 1287 | + set_bit(mpp->var->device_type, &mpp->queue->dev_active_flags); |
|---|
| 1288 | + return 0; |
|---|
| 1289 | +} |
|---|
| 1290 | + |
|---|
| 1264 | 1291 | static int rkvdec_3328_iommu_hdl(struct iommu_domain *iommu, |
|---|
| 1265 | 1292 | struct device *iommu_dev, |
|---|
| 1266 | 1293 | unsigned long iova, |
|---|
| .. | .. |
|---|
| 1311 | 1338 | struct rkvdec_dev *dec = to_rkvdec_dev(mpp); |
|---|
| 1312 | 1339 | |
|---|
| 1313 | 1340 | mutex_init(&dec->set_clk_lock); |
|---|
| 1314 | | - dec->parent_devfreq = devfreq_get_devfreq_by_phandle(mpp->dev, 0); |
|---|
| 1341 | + dec->parent_devfreq = devfreq_get_devfreq_by_phandle(mpp->dev, "rkvdec_devfreq", 0); |
|---|
| 1315 | 1342 | if (IS_ERR_OR_NULL(dec->parent_devfreq)) { |
|---|
| 1316 | 1343 | if (PTR_ERR(dec->parent_devfreq) == -EPROBE_DEFER) { |
|---|
| 1317 | 1344 | dev_warn(mpp->dev, "parent devfreq is not ready, retry\n"); |
|---|
| .. | .. |
|---|
| 1402 | 1429 | goto done; |
|---|
| 1403 | 1430 | } |
|---|
| 1404 | 1431 | dec->aux_iova = -1; |
|---|
| 1405 | | - mpp->iommu_info->hdl = rkvdec_3328_iommu_hdl; |
|---|
| 1432 | + mpp->fault_handler = rkvdec_3328_iommu_hdl; |
|---|
| 1406 | 1433 | |
|---|
| 1407 | 1434 | ret = rkvdec_devfreq_init(mpp); |
|---|
| 1408 | 1435 | done: |
|---|
| .. | .. |
|---|
| 1510 | 1537 | |
|---|
| 1511 | 1538 | dec->grf_changed = mpp_grf_is_changed(mpp->grf_info); |
|---|
| 1512 | 1539 | mpp_set_grf(mpp->grf_info); |
|---|
| 1540 | + |
|---|
| 1541 | + return 0; |
|---|
| 1542 | +} |
|---|
| 1543 | + |
|---|
| 1544 | +static int rkvdec_3036_set_grf(struct mpp_dev *mpp) |
|---|
| 1545 | +{ |
|---|
| 1546 | + int grf_changed; |
|---|
| 1547 | + struct mpp_dev *loop = NULL, *n; |
|---|
| 1548 | + struct mpp_taskqueue *queue = mpp->queue; |
|---|
| 1549 | + bool pd_is_on; |
|---|
| 1550 | + |
|---|
| 1551 | + grf_changed = mpp_grf_is_changed(mpp->grf_info); |
|---|
| 1552 | + if (grf_changed) { |
|---|
| 1553 | + |
|---|
| 1554 | + /* |
|---|
| 1555 | + * in this case, devices share the queue also share the same pd&clk, |
|---|
| 1556 | + * so use mpp->dev's pd to control all the process is okay |
|---|
| 1557 | + */ |
|---|
| 1558 | + pd_is_on = rockchip_pmu_pd_is_on(mpp->dev); |
|---|
| 1559 | + if (!pd_is_on) |
|---|
| 1560 | + rockchip_pmu_pd_on(mpp->dev); |
|---|
| 1561 | + mpp->hw_ops->clk_on(mpp); |
|---|
| 1562 | + |
|---|
| 1563 | + list_for_each_entry_safe(loop, n, &queue->dev_list, queue_link) { |
|---|
| 1564 | + if (test_bit(loop->var->device_type, &queue->dev_active_flags)) { |
|---|
| 1565 | + mpp_set_grf(loop->grf_info); |
|---|
| 1566 | + if (loop->hw_ops->clk_on) |
|---|
| 1567 | + loop->hw_ops->clk_on(loop); |
|---|
| 1568 | + if (loop->hw_ops->reset) |
|---|
| 1569 | + loop->hw_ops->reset(loop); |
|---|
| 1570 | + rockchip_iommu_disable(loop->dev); |
|---|
| 1571 | + if (loop->hw_ops->clk_off) |
|---|
| 1572 | + loop->hw_ops->clk_off(loop); |
|---|
| 1573 | + clear_bit(loop->var->device_type, &queue->dev_active_flags); |
|---|
| 1574 | + } |
|---|
| 1575 | + } |
|---|
| 1576 | + |
|---|
| 1577 | + mpp_set_grf(mpp->grf_info); |
|---|
| 1578 | + rockchip_iommu_enable(mpp->dev); |
|---|
| 1579 | + set_bit(mpp->var->device_type, &queue->dev_active_flags); |
|---|
| 1580 | + |
|---|
| 1581 | + mpp->hw_ops->clk_off(mpp); |
|---|
| 1582 | + if (!pd_is_on) |
|---|
| 1583 | + rockchip_pmu_pd_off(mpp->dev); |
|---|
| 1584 | + } |
|---|
| 1585 | + |
|---|
| 1513 | 1586 | |
|---|
| 1514 | 1587 | return 0; |
|---|
| 1515 | 1588 | } |
|---|
| .. | .. |
|---|
| 1629 | 1702 | |
|---|
| 1630 | 1703 | mpp_debug_enter(); |
|---|
| 1631 | 1704 | if (dec->rst_a && dec->rst_h) { |
|---|
| 1632 | | - rockchip_pmu_idle_request(mpp->dev, true); |
|---|
| 1705 | + mpp_pmu_idle_request(mpp, true); |
|---|
| 1633 | 1706 | mpp_safe_reset(dec->rst_niu_a); |
|---|
| 1634 | 1707 | mpp_safe_reset(dec->rst_niu_h); |
|---|
| 1635 | 1708 | mpp_safe_reset(dec->rst_a); |
|---|
| .. | .. |
|---|
| 1645 | 1718 | mpp_safe_unreset(dec->rst_core); |
|---|
| 1646 | 1719 | mpp_safe_unreset(dec->rst_cabac); |
|---|
| 1647 | 1720 | mpp_safe_unreset(dec->rst_hevc_cabac); |
|---|
| 1648 | | - rockchip_pmu_idle_request(mpp->dev, false); |
|---|
| 1721 | + mpp_pmu_idle_request(mpp, false); |
|---|
| 1649 | 1722 | } |
|---|
| 1650 | 1723 | mpp_debug_leave(); |
|---|
| 1651 | 1724 | |
|---|
| .. | .. |
|---|
| 1654 | 1727 | |
|---|
| 1655 | 1728 | static int rkvdec_sip_reset(struct mpp_dev *mpp) |
|---|
| 1656 | 1729 | { |
|---|
| 1657 | | - struct rkvdec_dev *dec = to_rkvdec_dev(mpp); |
|---|
| 1730 | + if (IS_REACHABLE(CONFIG_ROCKCHIP_SIP)) { |
|---|
| 1731 | + /* The reset flow in arm trustzone firmware */ |
|---|
| 1732 | + struct rkvdec_dev *dec = to_rkvdec_dev(mpp); |
|---|
| 1658 | 1733 | |
|---|
| 1659 | | -/* The reset flow in arm trustzone firmware */ |
|---|
| 1660 | | -#if IS_ENABLED(CONFIG_ROCKCHIP_SIP) |
|---|
| 1661 | | - mutex_lock(&dec->sip_reset_lock); |
|---|
| 1662 | | - sip_smc_vpu_reset(0, 0, 0); |
|---|
| 1663 | | - mutex_unlock(&dec->sip_reset_lock); |
|---|
| 1734 | + mutex_lock(&dec->sip_reset_lock); |
|---|
| 1735 | + sip_smc_vpu_reset(0, 0, 0); |
|---|
| 1736 | + mutex_unlock(&dec->sip_reset_lock); |
|---|
| 1664 | 1737 | |
|---|
| 1665 | | - return 0; |
|---|
| 1666 | | -#else |
|---|
| 1667 | | - return rkvdec_reset(mpp); |
|---|
| 1668 | | -#endif |
|---|
| 1738 | + return 0; |
|---|
| 1739 | + } else { |
|---|
| 1740 | + return rkvdec_reset(mpp); |
|---|
| 1741 | + } |
|---|
| 1669 | 1742 | } |
|---|
| 1670 | 1743 | |
|---|
| 1671 | 1744 | static struct mpp_hw_ops rkvdec_v1_hw_ops = { |
|---|
| .. | .. |
|---|
| 1687 | 1760 | .reduce_freq = rkvdec_reduce_freq, |
|---|
| 1688 | 1761 | .reset = rkvdec_reset, |
|---|
| 1689 | 1762 | .set_grf = px30_workaround_combo_switch_grf, |
|---|
| 1763 | +}; |
|---|
| 1764 | + |
|---|
| 1765 | +static struct mpp_hw_ops rkvdec_3036_hw_ops = { |
|---|
| 1766 | + .init = rkvdec_3036_init, |
|---|
| 1767 | + .clk_on = rkvdec_clk_on, |
|---|
| 1768 | + .clk_off = rkvdec_clk_off, |
|---|
| 1769 | + .get_freq = rkvdec_get_freq, |
|---|
| 1770 | + .set_freq = rkvdec_set_freq, |
|---|
| 1771 | + .reduce_freq = rkvdec_reduce_freq, |
|---|
| 1772 | + .reset = rkvdec_reset, |
|---|
| 1773 | + .set_grf = rkvdec_3036_set_grf, |
|---|
| 1690 | 1774 | }; |
|---|
| 1691 | 1775 | |
|---|
| 1692 | 1776 | static struct mpp_hw_ops rkvdec_3399_hw_ops = { |
|---|
| .. | .. |
|---|
| 1713 | 1797 | static struct mpp_dev_ops rkvdec_v1_dev_ops = { |
|---|
| 1714 | 1798 | .alloc_task = rkvdec_alloc_task, |
|---|
| 1715 | 1799 | .run = rkvdec_run, |
|---|
| 1800 | + .irq = rkvdec_irq, |
|---|
| 1801 | + .isr = rkvdec_isr, |
|---|
| 1802 | + .finish = rkvdec_finish, |
|---|
| 1803 | + .result = rkvdec_result, |
|---|
| 1804 | + .free_task = rkvdec_free_task, |
|---|
| 1805 | +}; |
|---|
| 1806 | + |
|---|
| 1807 | +static struct mpp_dev_ops rkvdec_px30_dev_ops = { |
|---|
| 1808 | + .alloc_task = rkvdec_alloc_task, |
|---|
| 1809 | + .run = rkvdec_px30_run, |
|---|
| 1716 | 1810 | .irq = rkvdec_irq, |
|---|
| 1717 | 1811 | .isr = rkvdec_isr, |
|---|
| 1718 | 1812 | .finish = rkvdec_finish, |
|---|
| .. | .. |
|---|
| 1769 | 1863 | .dev_ops = &rkvdec_v1_dev_ops, |
|---|
| 1770 | 1864 | }; |
|---|
| 1771 | 1865 | |
|---|
| 1866 | +static const struct mpp_dev_var rk_hevcdec_3036_data = { |
|---|
| 1867 | + .device_type = MPP_DEVICE_HEVC_DEC, |
|---|
| 1868 | + .hw_info = &rk_hevcdec_hw_info, |
|---|
| 1869 | + .trans_info = rk_hevcdec_trans, |
|---|
| 1870 | + .hw_ops = &rkvdec_3036_hw_ops, |
|---|
| 1871 | + .dev_ops = &rkvdec_v1_dev_ops, |
|---|
| 1872 | +}; |
|---|
| 1873 | + |
|---|
| 1772 | 1874 | static const struct mpp_dev_var rk_hevcdec_3368_data = { |
|---|
| 1773 | 1875 | .device_type = MPP_DEVICE_HEVC_DEC, |
|---|
| 1774 | 1876 | .hw_info = &rk_hevcdec_hw_info, |
|---|
| .. | .. |
|---|
| 1782 | 1884 | .hw_info = &rk_hevcdec_hw_info, |
|---|
| 1783 | 1885 | .trans_info = rk_hevcdec_trans, |
|---|
| 1784 | 1886 | .hw_ops = &rkvdec_px30_hw_ops, |
|---|
| 1785 | | - .dev_ops = &rkvdec_v1_dev_ops, |
|---|
| 1887 | + .dev_ops = &rkvdec_px30_dev_ops, |
|---|
| 1786 | 1888 | }; |
|---|
| 1787 | 1889 | |
|---|
| 1788 | 1890 | static const struct mpp_dev_var rkvdec_v1_data = { |
|---|
| .. | .. |
|---|
| 1826 | 1928 | { |
|---|
| 1827 | 1929 | .compatible = "rockchip,hevc-decoder-px30", |
|---|
| 1828 | 1930 | .data = &rk_hevcdec_px30_data, |
|---|
| 1931 | + }, |
|---|
| 1932 | +#endif |
|---|
| 1933 | +#ifdef CONFIG_CPU_RK3036 |
|---|
| 1934 | + { |
|---|
| 1935 | + .compatible = "rockchip,hevc-decoder-rk3036", |
|---|
| 1936 | + .data = &rk_hevcdec_3036_data, |
|---|
| 1829 | 1937 | }, |
|---|
| 1830 | 1938 | #endif |
|---|
| 1831 | 1939 | #ifdef CONFIG_CPU_RK3368 |
|---|
| .. | .. |
|---|
| 1873 | 1981 | return -ENOMEM; |
|---|
| 1874 | 1982 | |
|---|
| 1875 | 1983 | mpp = &dec->mpp; |
|---|
| 1876 | | - platform_set_drvdata(pdev, dec); |
|---|
| 1984 | + platform_set_drvdata(pdev, mpp); |
|---|
| 1877 | 1985 | |
|---|
| 1878 | 1986 | if (pdev->dev.of_node) { |
|---|
| 1879 | 1987 | match = of_match_node(mpp_rkvdec_dt_match, |
|---|
| .. | .. |
|---|
| 1919 | 2027 | return 0; |
|---|
| 1920 | 2028 | } |
|---|
| 1921 | 2029 | |
|---|
| 1922 | | -static void rkvdec_shutdown(struct platform_device *pdev) |
|---|
| 1923 | | -{ |
|---|
| 1924 | | - int ret; |
|---|
| 1925 | | - int val; |
|---|
| 1926 | | - struct device *dev = &pdev->dev; |
|---|
| 1927 | | - struct rkvdec_dev *dec = platform_get_drvdata(pdev); |
|---|
| 1928 | | - struct mpp_dev *mpp = &dec->mpp; |
|---|
| 1929 | | - |
|---|
| 1930 | | - dev_info(dev, "shutdown device\n"); |
|---|
| 1931 | | - |
|---|
| 1932 | | - atomic_inc(&mpp->srv->shutdown_request); |
|---|
| 1933 | | - ret = readx_poll_timeout(atomic_read, |
|---|
| 1934 | | - &mpp->task_count, |
|---|
| 1935 | | - val, val == 0, 20000, 200000); |
|---|
| 1936 | | - if (ret == -ETIMEDOUT) |
|---|
| 1937 | | - dev_err(dev, "wait total running time out\n"); |
|---|
| 1938 | | -} |
|---|
| 1939 | | - |
|---|
| 1940 | 2030 | struct platform_driver rockchip_rkvdec_driver = { |
|---|
| 1941 | 2031 | .probe = rkvdec_probe, |
|---|
| 1942 | 2032 | .remove = rkvdec_remove, |
|---|
| 1943 | | - .shutdown = rkvdec_shutdown, |
|---|
| 2033 | + .shutdown = mpp_dev_shutdown, |
|---|
| 1944 | 2034 | .driver = { |
|---|
| 1945 | 2035 | .name = RKVDEC_DRIVER_NAME, |
|---|
| 1946 | 2036 | .of_match_table = of_match_ptr(mpp_rkvdec_dt_match), |
|---|