.. | .. |
---|
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; |
---|
.. | .. |
---|
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 | |
---|
.. | .. |
---|
1265 | 1281 | return px30_workaround_combo_init(mpp); |
---|
1266 | 1282 | } |
---|
1267 | 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 | + |
---|
1268 | 1291 | static int rkvdec_3328_iommu_hdl(struct iommu_domain *iommu, |
---|
1269 | 1292 | struct device *iommu_dev, |
---|
1270 | 1293 | unsigned long iova, |
---|
.. | .. |
---|
1315 | 1338 | struct rkvdec_dev *dec = to_rkvdec_dev(mpp); |
---|
1316 | 1339 | |
---|
1317 | 1340 | mutex_init(&dec->set_clk_lock); |
---|
1318 | | - 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); |
---|
1319 | 1342 | if (IS_ERR_OR_NULL(dec->parent_devfreq)) { |
---|
1320 | 1343 | if (PTR_ERR(dec->parent_devfreq) == -EPROBE_DEFER) { |
---|
1321 | 1344 | dev_warn(mpp->dev, "parent devfreq is not ready, retry\n"); |
---|
.. | .. |
---|
1406 | 1429 | goto done; |
---|
1407 | 1430 | } |
---|
1408 | 1431 | dec->aux_iova = -1; |
---|
1409 | | - mpp->iommu_info->hdl = rkvdec_3328_iommu_hdl; |
---|
| 1432 | + mpp->fault_handler = rkvdec_3328_iommu_hdl; |
---|
1410 | 1433 | |
---|
1411 | 1434 | ret = rkvdec_devfreq_init(mpp); |
---|
1412 | 1435 | done: |
---|
.. | .. |
---|
1514 | 1537 | |
---|
1515 | 1538 | dec->grf_changed = mpp_grf_is_changed(mpp->grf_info); |
---|
1516 | 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 | + |
---|
1517 | 1586 | |
---|
1518 | 1587 | return 0; |
---|
1519 | 1588 | } |
---|
.. | .. |
---|
1658 | 1727 | |
---|
1659 | 1728 | static int rkvdec_sip_reset(struct mpp_dev *mpp) |
---|
1660 | 1729 | { |
---|
1661 | | - 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); |
---|
1662 | 1733 | |
---|
1663 | | -/* The reset flow in arm trustzone firmware */ |
---|
1664 | | -#if IS_ENABLED(CONFIG_ROCKCHIP_SIP) |
---|
1665 | | - mutex_lock(&dec->sip_reset_lock); |
---|
1666 | | - sip_smc_vpu_reset(0, 0, 0); |
---|
1667 | | - 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); |
---|
1668 | 1737 | |
---|
1669 | | - return 0; |
---|
1670 | | -#else |
---|
1671 | | - return rkvdec_reset(mpp); |
---|
1672 | | -#endif |
---|
| 1738 | + return 0; |
---|
| 1739 | + } else { |
---|
| 1740 | + return rkvdec_reset(mpp); |
---|
| 1741 | + } |
---|
1673 | 1742 | } |
---|
1674 | 1743 | |
---|
1675 | 1744 | static struct mpp_hw_ops rkvdec_v1_hw_ops = { |
---|
.. | .. |
---|
1691 | 1760 | .reduce_freq = rkvdec_reduce_freq, |
---|
1692 | 1761 | .reset = rkvdec_reset, |
---|
1693 | 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, |
---|
1694 | 1774 | }; |
---|
1695 | 1775 | |
---|
1696 | 1776 | static struct mpp_hw_ops rkvdec_3399_hw_ops = { |
---|
.. | .. |
---|
1717 | 1797 | static struct mpp_dev_ops rkvdec_v1_dev_ops = { |
---|
1718 | 1798 | .alloc_task = rkvdec_alloc_task, |
---|
1719 | 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, |
---|
1720 | 1810 | .irq = rkvdec_irq, |
---|
1721 | 1811 | .isr = rkvdec_isr, |
---|
1722 | 1812 | .finish = rkvdec_finish, |
---|
.. | .. |
---|
1773 | 1863 | .dev_ops = &rkvdec_v1_dev_ops, |
---|
1774 | 1864 | }; |
---|
1775 | 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 | + |
---|
1776 | 1874 | static const struct mpp_dev_var rk_hevcdec_3368_data = { |
---|
1777 | 1875 | .device_type = MPP_DEVICE_HEVC_DEC, |
---|
1778 | 1876 | .hw_info = &rk_hevcdec_hw_info, |
---|
.. | .. |
---|
1786 | 1884 | .hw_info = &rk_hevcdec_hw_info, |
---|
1787 | 1885 | .trans_info = rk_hevcdec_trans, |
---|
1788 | 1886 | .hw_ops = &rkvdec_px30_hw_ops, |
---|
1789 | | - .dev_ops = &rkvdec_v1_dev_ops, |
---|
| 1887 | + .dev_ops = &rkvdec_px30_dev_ops, |
---|
1790 | 1888 | }; |
---|
1791 | 1889 | |
---|
1792 | 1890 | static const struct mpp_dev_var rkvdec_v1_data = { |
---|
.. | .. |
---|
1830 | 1928 | { |
---|
1831 | 1929 | .compatible = "rockchip,hevc-decoder-px30", |
---|
1832 | 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, |
---|
1833 | 1937 | }, |
---|
1834 | 1938 | #endif |
---|
1835 | 1939 | #ifdef CONFIG_CPU_RK3368 |
---|
.. | .. |
---|
1877 | 1981 | return -ENOMEM; |
---|
1878 | 1982 | |
---|
1879 | 1983 | mpp = &dec->mpp; |
---|
1880 | | - platform_set_drvdata(pdev, dec); |
---|
| 1984 | + platform_set_drvdata(pdev, mpp); |
---|
1881 | 1985 | |
---|
1882 | 1986 | if (pdev->dev.of_node) { |
---|
1883 | 1987 | match = of_match_node(mpp_rkvdec_dt_match, |
---|
.. | .. |
---|
1923 | 2027 | return 0; |
---|
1924 | 2028 | } |
---|
1925 | 2029 | |
---|
1926 | | -static void rkvdec_shutdown(struct platform_device *pdev) |
---|
1927 | | -{ |
---|
1928 | | - int ret; |
---|
1929 | | - int val; |
---|
1930 | | - struct device *dev = &pdev->dev; |
---|
1931 | | - struct rkvdec_dev *dec = platform_get_drvdata(pdev); |
---|
1932 | | - struct mpp_dev *mpp = &dec->mpp; |
---|
1933 | | - |
---|
1934 | | - dev_info(dev, "shutdown device\n"); |
---|
1935 | | - |
---|
1936 | | - atomic_inc(&mpp->srv->shutdown_request); |
---|
1937 | | - ret = readx_poll_timeout(atomic_read, |
---|
1938 | | - &mpp->task_count, |
---|
1939 | | - val, val == 0, 20000, 200000); |
---|
1940 | | - if (ret == -ETIMEDOUT) |
---|
1941 | | - dev_err(dev, "wait total running time out\n"); |
---|
1942 | | -} |
---|
1943 | | - |
---|
1944 | 2030 | struct platform_driver rockchip_rkvdec_driver = { |
---|
1945 | 2031 | .probe = rkvdec_probe, |
---|
1946 | 2032 | .remove = rkvdec_remove, |
---|
1947 | | - .shutdown = rkvdec_shutdown, |
---|
| 2033 | + .shutdown = mpp_dev_shutdown, |
---|
1948 | 2034 | .driver = { |
---|
1949 | 2035 | .name = RKVDEC_DRIVER_NAME, |
---|
1950 | 2036 | .of_match_table = of_match_ptr(mpp_rkvdec_dt_match), |
---|