.. | .. |
---|
1206 | 1206 | unsigned long lock_flags = 0; |
---|
1207 | 1207 | int i = 0; |
---|
1208 | 1208 | |
---|
| 1209 | + if (stream->id == RKISP_STREAM_VIR) |
---|
| 1210 | + return 0; |
---|
| 1211 | + |
---|
1209 | 1212 | if (!stream->next_buf && stream->streaming && |
---|
1210 | 1213 | dev->dmarx_dev.trigger == T_MANUAL && |
---|
1211 | 1214 | is_rdbk_stream(stream)) |
---|
.. | .. |
---|
1218 | 1221 | (!interlaced || |
---|
1219 | 1222 | (stream->u.sp.field_rec == RKISP_FIELD_ODD && |
---|
1220 | 1223 | stream->u.sp.field == RKISP_FIELD_EVEN))) { |
---|
| 1224 | + struct rkisp_stream *vir = &dev->cap_dev.stream[RKISP_STREAM_VIR]; |
---|
1221 | 1225 | struct vb2_buffer *vb2_buf = &stream->curr_buf->vb.vb2_buf; |
---|
1222 | 1226 | u64 ns = 0; |
---|
1223 | 1227 | |
---|
.. | .. |
---|
1268 | 1272 | rdbk_frame_end(stream); |
---|
1269 | 1273 | } |
---|
1270 | 1274 | } else { |
---|
1271 | | - rkisp_stream_buf_done(stream, stream->curr_buf); |
---|
| 1275 | + if (vir->streaming && vir->conn_id == stream->id) { |
---|
| 1276 | + spin_lock_irqsave(&vir->vbq_lock, lock_flags); |
---|
| 1277 | + list_add_tail(&stream->curr_buf->queue, |
---|
| 1278 | + &dev->cap_dev.vir_cpy.queue); |
---|
| 1279 | + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); |
---|
| 1280 | + if (!completion_done(&dev->cap_dev.vir_cpy.cmpl)) |
---|
| 1281 | + complete(&dev->cap_dev.vir_cpy.cmpl); |
---|
| 1282 | + } else { |
---|
| 1283 | + rkisp_stream_buf_done(stream, stream->curr_buf); |
---|
| 1284 | + } |
---|
1272 | 1285 | } |
---|
1273 | 1286 | |
---|
1274 | 1287 | stream->curr_buf = NULL; |
---|
.. | .. |
---|
1378 | 1391 | CIF_MI_CTRL_BURST_LEN_CHROM_16; |
---|
1379 | 1392 | stream->interlaced = false; |
---|
1380 | 1393 | } |
---|
| 1394 | + |
---|
| 1395 | +static void vir_cpy_image(struct work_struct *work) |
---|
| 1396 | +{ |
---|
| 1397 | + struct rkisp_vir_cpy *cpy = |
---|
| 1398 | + container_of(work, struct rkisp_vir_cpy, work); |
---|
| 1399 | + struct rkisp_stream *vir = cpy->stream; |
---|
| 1400 | + struct rkisp_buffer *src_buf = NULL; |
---|
| 1401 | + unsigned long lock_flags = 0; |
---|
| 1402 | + u32 i; |
---|
| 1403 | + |
---|
| 1404 | + v4l2_dbg(1, rkisp_debug, &vir->ispdev->v4l2_dev, |
---|
| 1405 | + "%s enter\n", __func__); |
---|
| 1406 | + |
---|
| 1407 | + vir->streaming = true; |
---|
| 1408 | + spin_lock_irqsave(&vir->vbq_lock, lock_flags); |
---|
| 1409 | + if (!list_empty(&cpy->queue)) { |
---|
| 1410 | + src_buf = list_first_entry(&cpy->queue, |
---|
| 1411 | + struct rkisp_buffer, queue); |
---|
| 1412 | + list_del(&src_buf->queue); |
---|
| 1413 | + } |
---|
| 1414 | + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); |
---|
| 1415 | + |
---|
| 1416 | + while (src_buf || vir->streaming) { |
---|
| 1417 | + if (vir->stopping || !vir->streaming) |
---|
| 1418 | + goto end; |
---|
| 1419 | + |
---|
| 1420 | + if (!src_buf) |
---|
| 1421 | + wait_for_completion(&cpy->cmpl); |
---|
| 1422 | + |
---|
| 1423 | + vir->frame_end = false; |
---|
| 1424 | + spin_lock_irqsave(&vir->vbq_lock, lock_flags); |
---|
| 1425 | + |
---|
| 1426 | + if (!src_buf && !list_empty(&cpy->queue)) { |
---|
| 1427 | + src_buf = list_first_entry(&cpy->queue, |
---|
| 1428 | + struct rkisp_buffer, queue); |
---|
| 1429 | + list_del(&src_buf->queue); |
---|
| 1430 | + } |
---|
| 1431 | + |
---|
| 1432 | + if (src_buf && !vir->curr_buf && !list_empty(&vir->buf_queue)) { |
---|
| 1433 | + vir->curr_buf = list_first_entry(&vir->buf_queue, |
---|
| 1434 | + struct rkisp_buffer, queue); |
---|
| 1435 | + list_del(&vir->curr_buf->queue); |
---|
| 1436 | + } |
---|
| 1437 | + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); |
---|
| 1438 | + |
---|
| 1439 | + if (!vir->curr_buf || !src_buf) |
---|
| 1440 | + goto end; |
---|
| 1441 | + |
---|
| 1442 | + for (i = 0; i < vir->out_isp_fmt.mplanes; i++) { |
---|
| 1443 | + u32 payload_size = vir->out_fmt.plane_fmt[i].sizeimage; |
---|
| 1444 | + void *src = vb2_plane_vaddr(&src_buf->vb.vb2_buf, i); |
---|
| 1445 | + void *dst = vb2_plane_vaddr(&vir->curr_buf->vb.vb2_buf, i); |
---|
| 1446 | + |
---|
| 1447 | + if (!src || !dst) |
---|
| 1448 | + break; |
---|
| 1449 | + vb2_set_plane_payload(&vir->curr_buf->vb.vb2_buf, i, payload_size); |
---|
| 1450 | + memcpy(dst, src, payload_size); |
---|
| 1451 | + } |
---|
| 1452 | + |
---|
| 1453 | + vir->curr_buf->vb.sequence = src_buf->vb.sequence; |
---|
| 1454 | + vir->curr_buf->vb.vb2_buf.timestamp = src_buf->vb.vb2_buf.timestamp; |
---|
| 1455 | + vb2_buffer_done(&vir->curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); |
---|
| 1456 | + vir->curr_buf = NULL; |
---|
| 1457 | +end: |
---|
| 1458 | + if (src_buf) |
---|
| 1459 | + vb2_buffer_done(&src_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); |
---|
| 1460 | + src_buf = NULL; |
---|
| 1461 | + spin_lock_irqsave(&vir->vbq_lock, lock_flags); |
---|
| 1462 | + |
---|
| 1463 | + if (!list_empty(&cpy->queue)) { |
---|
| 1464 | + src_buf = list_first_entry(&cpy->queue, |
---|
| 1465 | + struct rkisp_buffer, queue); |
---|
| 1466 | + list_del(&src_buf->queue); |
---|
| 1467 | + } else if (vir->stopping) { |
---|
| 1468 | + vir->streaming = false; |
---|
| 1469 | + } |
---|
| 1470 | + |
---|
| 1471 | + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); |
---|
| 1472 | + } |
---|
| 1473 | + |
---|
| 1474 | + vir->frame_end = true; |
---|
| 1475 | + |
---|
| 1476 | + if (vir->stopping) { |
---|
| 1477 | + vir->stopping = false; |
---|
| 1478 | + vir->streaming = false; |
---|
| 1479 | + wake_up(&vir->done); |
---|
| 1480 | + } |
---|
| 1481 | + |
---|
| 1482 | + v4l2_dbg(1, rkisp_debug, &vir->ispdev->v4l2_dev, |
---|
| 1483 | + "%s exit\n", __func__); |
---|
| 1484 | +} |
---|
| 1485 | + |
---|
1381 | 1486 | |
---|
1382 | 1487 | /* |
---|
1383 | 1488 | * Most of registers inside rockchip isp1 have shadow register since |
---|
.. | .. |
---|
1571 | 1676 | if (!stream->streaming) |
---|
1572 | 1677 | goto end; |
---|
1573 | 1678 | |
---|
| 1679 | + if (stream->id == RKISP_STREAM_VIR) { |
---|
| 1680 | + stream->stopping = true; |
---|
| 1681 | + wait_event_timeout(stream->done, |
---|
| 1682 | + stream->frame_end, |
---|
| 1683 | + msecs_to_jiffies(500)); |
---|
| 1684 | + stream->streaming = false; |
---|
| 1685 | + stream->stopping = false; |
---|
| 1686 | + destroy_buf_queue(stream, VB2_BUF_STATE_ERROR); |
---|
| 1687 | + |
---|
| 1688 | + if (!completion_done(&dev->cap_dev.vir_cpy.cmpl)) |
---|
| 1689 | + complete(&dev->cap_dev.vir_cpy.cmpl); |
---|
| 1690 | + stream->conn_id = -1; |
---|
| 1691 | + goto end; |
---|
| 1692 | + } |
---|
| 1693 | + |
---|
1574 | 1694 | rkisp_stream_stop(stream); |
---|
1575 | 1695 | if (stream->id == RKISP_STREAM_MP || |
---|
1576 | 1696 | stream->id == RKISP_STREAM_SP) { |
---|
.. | .. |
---|
1650 | 1770 | if (WARN_ON(stream->streaming)) { |
---|
1651 | 1771 | mutex_unlock(&dev->hw_dev->dev_lock); |
---|
1652 | 1772 | return -EBUSY; |
---|
| 1773 | + } |
---|
| 1774 | + |
---|
| 1775 | + if (stream->id == RKISP_STREAM_VIR) { |
---|
| 1776 | + struct rkisp_stream *t = &dev->cap_dev.stream[stream->conn_id]; |
---|
| 1777 | + |
---|
| 1778 | + if (t->streaming) { |
---|
| 1779 | + INIT_WORK(&dev->cap_dev.vir_cpy.work, vir_cpy_image); |
---|
| 1780 | + init_completion(&dev->cap_dev.vir_cpy.cmpl); |
---|
| 1781 | + INIT_LIST_HEAD(&dev->cap_dev.vir_cpy.queue); |
---|
| 1782 | + dev->cap_dev.vir_cpy.stream = stream; |
---|
| 1783 | + schedule_work(&dev->cap_dev.vir_cpy.work); |
---|
| 1784 | + ret = 0; |
---|
| 1785 | + } else { |
---|
| 1786 | + v4l2_err(&dev->v4l2_dev, |
---|
| 1787 | + "no stream enable for iqtool\n"); |
---|
| 1788 | + destroy_buf_queue(stream, VB2_BUF_STATE_QUEUED); |
---|
| 1789 | + ret = -EINVAL; |
---|
| 1790 | + } |
---|
| 1791 | + |
---|
| 1792 | + mutex_unlock(&dev->hw_dev->dev_lock); |
---|
| 1793 | + |
---|
| 1794 | + return ret; |
---|
1653 | 1795 | } |
---|
1654 | 1796 | |
---|
1655 | 1797 | memset(&stream->dbg, 0, sizeof(stream->dbg)); |
---|
.. | .. |
---|
1787 | 1929 | |
---|
1788 | 1930 | switch (id) { |
---|
1789 | 1931 | case RKISP_STREAM_SP: |
---|
1790 | | - strlcpy(vdev->name, SP_VDEV_NAME, |
---|
| 1932 | + strscpy(vdev->name, SP_VDEV_NAME, |
---|
1791 | 1933 | sizeof(vdev->name)); |
---|
1792 | 1934 | stream->ops = &rkisp_sp_streams_ops; |
---|
1793 | 1935 | stream->config = &rkisp_sp_stream_config; |
---|
.. | .. |
---|
1795 | 1937 | stream->config->fmt_size = ARRAY_SIZE(sp_fmts); |
---|
1796 | 1938 | break; |
---|
1797 | 1939 | case RKISP_STREAM_DMATX0: |
---|
1798 | | - strlcpy(vdev->name, DMATX0_VDEV_NAME, |
---|
| 1940 | + strscpy(vdev->name, DMATX0_VDEV_NAME, |
---|
1799 | 1941 | sizeof(vdev->name)); |
---|
1800 | 1942 | stream->ops = &rkisp2_dmatx0_streams_ops; |
---|
1801 | 1943 | stream->config = &rkisp2_dmatx0_stream_config; |
---|
1802 | 1944 | break; |
---|
1803 | 1945 | case RKISP_STREAM_DMATX2: |
---|
1804 | | - strlcpy(vdev->name, DMATX2_VDEV_NAME, |
---|
| 1946 | + strscpy(vdev->name, DMATX2_VDEV_NAME, |
---|
1805 | 1947 | sizeof(vdev->name)); |
---|
1806 | 1948 | stream->ops = &rkisp2_dmatx2_streams_ops; |
---|
1807 | 1949 | stream->config = &rkisp2_dmatx1_stream_config; |
---|
1808 | 1950 | break; |
---|
1809 | 1951 | case RKISP_STREAM_DMATX3: |
---|
1810 | | - strlcpy(vdev->name, DMATX3_VDEV_NAME, |
---|
| 1952 | + strscpy(vdev->name, DMATX3_VDEV_NAME, |
---|
1811 | 1953 | sizeof(vdev->name)); |
---|
1812 | 1954 | stream->ops = &rkisp2_dmatx3_streams_ops; |
---|
1813 | 1955 | stream->config = &rkisp2_dmatx3_stream_config; |
---|
1814 | 1956 | break; |
---|
| 1957 | + case RKISP_STREAM_VIR: |
---|
| 1958 | + strscpy(vdev->name, VIR_VDEV_NAME, |
---|
| 1959 | + sizeof(vdev->name)); |
---|
| 1960 | + stream->ops = NULL; |
---|
| 1961 | + stream->config = &rkisp_mp_stream_config; |
---|
| 1962 | + stream->conn_id = -1; |
---|
| 1963 | + break; |
---|
1815 | 1964 | default: |
---|
1816 | | - strlcpy(vdev->name, MP_VDEV_NAME, |
---|
| 1965 | + strscpy(vdev->name, MP_VDEV_NAME, |
---|
1817 | 1966 | sizeof(vdev->name)); |
---|
1818 | 1967 | stream->ops = &rkisp_mp_streams_ops; |
---|
1819 | 1968 | stream->config = &rkisp_mp_stream_config; |
---|
.. | .. |
---|
1857 | 2006 | ret = rkisp_stream_init(dev, RKISP_STREAM_DMATX3); |
---|
1858 | 2007 | if (ret < 0) |
---|
1859 | 2008 | goto err_free_tx2; |
---|
| 2009 | + ret = rkisp_stream_init(dev, RKISP_STREAM_VIR); |
---|
| 2010 | + if (ret < 0) |
---|
| 2011 | + goto err_free_tx3; |
---|
1860 | 2012 | |
---|
1861 | 2013 | return 0; |
---|
| 2014 | +err_free_tx3: |
---|
| 2015 | + rkisp_unregister_stream_vdev(&cap_dev->stream[RKISP_STREAM_DMATX3]); |
---|
1862 | 2016 | err_free_tx2: |
---|
1863 | 2017 | rkisp_unregister_stream_vdev(&cap_dev->stream[RKISP_STREAM_DMATX2]); |
---|
1864 | 2018 | err_free_tx0: |
---|
.. | .. |
---|
1886 | 2040 | rkisp_unregister_stream_vdev(stream); |
---|
1887 | 2041 | stream = &cap_dev->stream[RKISP_STREAM_DMATX3]; |
---|
1888 | 2042 | rkisp_unregister_stream_vdev(stream); |
---|
| 2043 | + stream = &cap_dev->stream[RKISP_STREAM_VIR]; |
---|
| 2044 | + rkisp_unregister_stream_vdev(stream); |
---|
1889 | 2045 | } |
---|
1890 | 2046 | |
---|
1891 | 2047 | /**************** Interrupter Handler ****************/ |
---|
.. | .. |
---|
1905 | 2061 | for (i = 0; i < RKISP_MAX_STREAM; ++i) { |
---|
1906 | 2062 | stream = &dev->cap_dev.stream[i]; |
---|
1907 | 2063 | |
---|
1908 | | - if (!(mis_val & CIF_MI_FRAME(stream))) |
---|
| 2064 | + if (!(mis_val & CIF_MI_FRAME(stream)) || stream->id == RKISP_STREAM_VIR) |
---|
1909 | 2065 | continue; |
---|
1910 | 2066 | |
---|
1911 | 2067 | if (i == RKISP_STREAM_DMATX0) |
---|