Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: mediatek: vcodec: add vp9 decoder driver for mt8186

Add vp9 single core decode driver to support mt8186.

[hverkuil: fix 3 small checkpatch warnings]

Signed-off-by: Mingjia Zhang <mingjia.zhang@mediatek.com>
Signed-off-by: Xiaoyong Lu <xiaoyong.lu@mediatek.com>
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Yunfei Dong and committed by
Mauro Carvalho Chehab
b0f407c1 d7365ae8

+195 -4
+194 -3
drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
··· 439 439 * @init_vsi: vsi used for initialized VP9 instance 440 440 * @vsi: vsi used for decoding/flush ... 441 441 * @core_vsi: vsi used for Core stage 442 + * 443 + * @sc_pfc: per frame context single core 442 444 * @counts_map: used map to counts_helper 443 445 * @counts_helper: counts table according to newest kernel spec 444 446 */ ··· 489 487 }; 490 488 struct vdec_vp9_slice_vsi *core_vsi; 491 489 490 + struct vdec_vp9_slice_pfc sc_pfc; 492 491 struct vdec_vp9_slice_counts_map counts_map; 493 492 struct v4l2_vp9_frame_symbol_counts counts_helper; 494 493 }; ··· 693 690 int offset = ((idx * sbs) >> tile_log2) << 3; 694 691 695 692 return offset < mi_num ? offset : mi_num; 693 + } 694 + 695 + static 696 + int vdec_vp9_slice_setup_single_from_src_to_dst(struct vdec_vp9_slice_instance *instance) 697 + { 698 + struct vb2_v4l2_buffer *src; 699 + struct vb2_v4l2_buffer *dst; 700 + 701 + src = v4l2_m2m_next_src_buf(instance->ctx->m2m_ctx); 702 + if (!src) 703 + return -EINVAL; 704 + 705 + dst = v4l2_m2m_next_dst_buf(instance->ctx->m2m_ctx); 706 + if (!dst) 707 + return -EINVAL; 708 + 709 + v4l2_m2m_buf_copy_metadata(src, dst, true); 710 + 711 + return 0; 696 712 } 697 713 698 714 static int vdec_vp9_slice_setup_lat_from_src_buf(struct vdec_vp9_slice_instance *instance, ··· 1589 1567 return 0; 1590 1568 } 1591 1569 1570 + static int vdec_vp9_slice_update_single(struct vdec_vp9_slice_instance *instance, 1571 + struct vdec_vp9_slice_pfc *pfc) 1572 + { 1573 + struct vdec_vp9_slice_vsi *vsi; 1574 + 1575 + vsi = &pfc->vsi; 1576 + memcpy(&pfc->state[0], &vsi->state, sizeof(vsi->state)); 1577 + 1578 + mtk_vcodec_debug(instance, "Frame %u Y_CRC %08x %08x %08x %08x\n", 1579 + pfc->seq, 1580 + vsi->state.crc[0], vsi->state.crc[1], 1581 + vsi->state.crc[2], vsi->state.crc[3]); 1582 + mtk_vcodec_debug(instance, "Frame %u C_CRC %08x %08x %08x %08x\n", 1583 + pfc->seq, 1584 + vsi->state.crc[4], vsi->state.crc[5], 1585 + vsi->state.crc[6], vsi->state.crc[7]); 1586 + 1587 + vdec_vp9_slice_update_prob(instance, vsi); 1588 + 1589 + instance->width = vsi->frame.uh.frame_width; 1590 + instance->height = vsi->frame.uh.frame_height; 1591 + instance->frame_type = vsi->frame.uh.frame_type; 1592 + instance->show_frame = vsi->frame.uh.show_frame; 1593 + 1594 + return 0; 1595 + } 1596 + 1592 1597 static int vdec_vp9_slice_update_lat(struct vdec_vp9_slice_instance *instance, 1593 1598 struct vdec_lat_buf *lat_buf, 1594 1599 struct vdec_vp9_slice_pfc *pfc) ··· 1739 1690 return 0; 1740 1691 } 1741 1692 1693 + static void vdec_vp9_slice_setup_single_buffer(struct vdec_vp9_slice_instance *instance, 1694 + struct vdec_vp9_slice_pfc *pfc, 1695 + struct vdec_vp9_slice_vsi *vsi, 1696 + struct mtk_vcodec_mem *bs, 1697 + struct vdec_fb *fb) 1698 + { 1699 + int i; 1700 + 1701 + vsi->bs.buf.dma_addr = bs->dma_addr; 1702 + vsi->bs.buf.size = bs->size; 1703 + vsi->bs.frame.dma_addr = bs->dma_addr; 1704 + vsi->bs.frame.size = bs->size; 1705 + 1706 + for (i = 0; i < 2; i++) { 1707 + vsi->mv[i].dma_addr = instance->mv[i].dma_addr; 1708 + vsi->mv[i].size = instance->mv[i].size; 1709 + } 1710 + for (i = 0; i < 2; i++) { 1711 + vsi->seg[i].dma_addr = instance->seg[i].dma_addr; 1712 + vsi->seg[i].size = instance->seg[i].size; 1713 + } 1714 + vsi->tile.dma_addr = instance->tile.dma_addr; 1715 + vsi->tile.size = instance->tile.size; 1716 + vsi->prob.dma_addr = instance->prob.dma_addr; 1717 + vsi->prob.size = instance->prob.size; 1718 + vsi->counts.dma_addr = instance->counts.dma_addr; 1719 + vsi->counts.size = instance->counts.size; 1720 + 1721 + vsi->row_info.buf = 0; 1722 + vsi->row_info.size = 0; 1723 + 1724 + vdec_vp9_slice_setup_core_buffer(instance, pfc, vsi, fb, NULL); 1725 + } 1726 + 1742 1727 static int vdec_vp9_slice_setup_core(struct vdec_vp9_slice_instance *instance, 1743 1728 struct vdec_fb *fb, 1744 1729 struct vdec_lat_buf *lat_buf, ··· 1792 1709 goto err; 1793 1710 1794 1711 vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[1]); 1712 + 1713 + return 0; 1714 + 1715 + err: 1716 + return ret; 1717 + } 1718 + 1719 + static int vdec_vp9_slice_setup_single(struct vdec_vp9_slice_instance *instance, 1720 + struct mtk_vcodec_mem *bs, 1721 + struct vdec_fb *fb, 1722 + struct vdec_vp9_slice_pfc *pfc) 1723 + { 1724 + struct vdec_vp9_slice_vsi *vsi = &pfc->vsi; 1725 + int ret; 1726 + 1727 + ret = vdec_vp9_slice_setup_single_from_src_to_dst(instance); 1728 + if (ret) 1729 + goto err; 1730 + 1731 + ret = vdec_vp9_slice_setup_pfc(instance, pfc); 1732 + if (ret) 1733 + goto err; 1734 + 1735 + ret = vdec_vp9_slice_alloc_working_buffer(instance, vsi); 1736 + if (ret) 1737 + goto err; 1738 + 1739 + vdec_vp9_slice_setup_single_buffer(instance, pfc, vsi, bs, fb); 1740 + vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[0]); 1741 + 1742 + ret = vdec_vp9_slice_setup_prob_buffer(instance, vsi); 1743 + if (ret) 1744 + goto err; 1745 + 1746 + ret = vdec_vp9_slice_setup_tile_buffer(instance, vsi, bs); 1747 + if (ret) 1748 + goto err; 1795 1749 1796 1750 return 0; 1797 1751 ··· 1933 1813 struct vdec_vp9_slice_instance *instance = h_vdec; 1934 1814 1935 1815 mtk_vcodec_debug(instance, "flush ...\n"); 1936 - 1937 - vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue); 1816 + if (instance->ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE) 1817 + vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue); 1938 1818 return vpu_dec_reset(&instance->vpu); 1939 1819 } 1940 1820 ··· 1984 1864 return -EINVAL; 1985 1865 } 1986 1866 1867 + return 0; 1868 + } 1869 + 1870 + static int vdec_vp9_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs, 1871 + struct vdec_fb *fb, bool *res_chg) 1872 + { 1873 + struct vdec_vp9_slice_instance *instance = h_vdec; 1874 + struct vdec_vp9_slice_pfc *pfc = &instance->sc_pfc; 1875 + struct vdec_vp9_slice_vsi *vsi; 1876 + struct mtk_vcodec_ctx *ctx; 1877 + int ret; 1878 + 1879 + if (!instance || !instance->ctx) 1880 + return -EINVAL; 1881 + ctx = instance->ctx; 1882 + 1883 + /* bs NULL means flush decoder */ 1884 + if (!bs) 1885 + return vdec_vp9_slice_flush(h_vdec, bs, fb, res_chg); 1886 + 1887 + fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx); 1888 + if (!fb) 1889 + return -EBUSY; 1890 + 1891 + vsi = &pfc->vsi; 1892 + 1893 + ret = vdec_vp9_slice_setup_single(instance, bs, fb, pfc); 1894 + if (ret) { 1895 + mtk_vcodec_err(instance, "Failed to setup VP9 single ret %d\n", ret); 1896 + return ret; 1897 + } 1898 + vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi); 1899 + 1900 + ret = vpu_dec_start(&instance->vpu, NULL, 0); 1901 + if (ret) { 1902 + mtk_vcodec_err(instance, "Failed to dec VP9 ret %d\n", ret); 1903 + return ret; 1904 + } 1905 + 1906 + ret = mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED, 1907 + WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); 1908 + /* update remote vsi if decode timeout */ 1909 + if (ret) { 1910 + mtk_vcodec_err(instance, "VP9 decode timeout %d\n", ret); 1911 + WRITE_ONCE(instance->vsi->state.timeout, 1); 1912 + } 1913 + 1914 + vpu_dec_end(&instance->vpu); 1915 + 1916 + vdec_vp9_slice_vsi_from_remote(vsi, instance->vsi, 0); 1917 + ret = vdec_vp9_slice_update_single(instance, pfc); 1918 + if (ret) { 1919 + mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret); 1920 + return ret; 1921 + } 1922 + 1923 + instance->ctx->decoded_frame_cnt++; 1987 1924 return 0; 1988 1925 } 1989 1926 ··· 2123 1946 return 0; 2124 1947 } 2125 1948 1949 + static int vdec_vp9_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, 1950 + struct vdec_fb *fb, bool *res_chg) 1951 + { 1952 + struct vdec_vp9_slice_instance *instance = h_vdec; 1953 + int ret; 1954 + 1955 + if (instance->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE) 1956 + ret = vdec_vp9_slice_single_decode(h_vdec, bs, fb, res_chg); 1957 + else 1958 + ret = vdec_vp9_slice_lat_decode(h_vdec, bs, fb, res_chg); 1959 + 1960 + return ret; 1961 + } 1962 + 2126 1963 static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf) 2127 1964 { 2128 1965 struct vdec_vp9_slice_instance *instance; ··· 2215 2024 2216 2025 const struct vdec_common_if vdec_vp9_slice_lat_if = { 2217 2026 .init = vdec_vp9_slice_init, 2218 - .decode = vdec_vp9_slice_lat_decode, 2027 + .decode = vdec_vp9_slice_decode, 2219 2028 .get_param = vdec_vp9_slice_get_param, 2220 2029 .deinit = vdec_vp9_slice_deinit, 2221 2030 };
+1 -1
drivers/media/platform/mediatek/vcodec/vdec_drv_if.c
··· 47 47 break; 48 48 case V4L2_PIX_FMT_VP9_FRAME: 49 49 ctx->dec_if = &vdec_vp9_slice_lat_if; 50 - ctx->hw_id = MTK_VDEC_LAT0; 50 + ctx->hw_id = IS_VDEC_LAT_ARCH(hw_arch) ? MTK_VDEC_LAT0 : MTK_VDEC_CORE; 51 51 break; 52 52 default: 53 53 return -EINVAL;