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