|
28 | 28 | #include "../include/linux/raspberrypi/vchiq.h"
|
29 | 29 | #include "../interface/vchiq_arm/vchiq_arm.h"
|
30 | 30 | #include "mmal-common.h"
|
| 31 | +#include "mmal-parameters.h" |
31 | 32 | #include "mmal-vchiq.h"
|
32 | 33 | #include "mmal-msg.h"
|
33 | 34 |
|
| 35 | +#include "../vc-sm-cma/vc_sm_knl.h" |
| 36 | + |
34 | 37 | /*
|
35 | 38 | * maximum number of components supported.
|
36 | 39 | * This matches the maximum permitted by default on the VPU
|
@@ -417,8 +420,13 @@ buffer_from_host(struct vchiq_mmal_instance *instance,
|
417 | 420 |
|
418 | 421 | /* buffer header */
|
419 | 422 | m.u.buffer_from_host.buffer_header.cmd = 0;
|
420 |
| - m.u.buffer_from_host.buffer_header.data = |
421 |
| - (u32)(unsigned long)buf->buffer; |
| 423 | + if (port->zero_copy) { |
| 424 | + m.u.buffer_from_host.buffer_header.data = buf->vc_handle; |
| 425 | + } else { |
| 426 | + m.u.buffer_from_host.buffer_header.data = |
| 427 | + (u32)(unsigned long)buf->buffer; |
| 428 | + } |
| 429 | + |
422 | 430 | m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
|
423 | 431 | if (port->type == MMAL_PORT_TYPE_OUTPUT) {
|
424 | 432 | m.u.buffer_from_host.buffer_header.length = 0;
|
@@ -584,6 +592,22 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance,
|
584 | 592 |
|
585 | 593 | msg_context->u.bulk.status = msg->h.status;
|
586 | 594 |
|
| 595 | + } else if (msg->u.buffer_from_host.is_zero_copy) { |
| 596 | + /* |
| 597 | + * Zero copy buffer, so nothing to do. |
| 598 | + * Copy buffer info and make callback. |
| 599 | + */ |
| 600 | + msg_context->u.bulk.buffer_used = |
| 601 | + msg->u.buffer_from_host.buffer_header.length; |
| 602 | + msg_context->u.bulk.mmal_flags = |
| 603 | + msg->u.buffer_from_host.buffer_header.flags; |
| 604 | + msg_context->u.bulk.dts = |
| 605 | + msg->u.buffer_from_host.buffer_header.dts; |
| 606 | + msg_context->u.bulk.pts = |
| 607 | + msg->u.buffer_from_host.buffer_header.pts; |
| 608 | + msg_context->u.bulk.cmd = |
| 609 | + msg->u.buffer_from_host.buffer_header.cmd; |
| 610 | + |
587 | 611 | } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
|
588 | 612 | /* empty buffer */
|
589 | 613 | if (msg->u.buffer_from_host.buffer_header.flags &
|
@@ -1530,6 +1554,9 @@ int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,
|
1530 | 1554 |
|
1531 | 1555 | mutex_unlock(&instance->vchiq_mutex);
|
1532 | 1556 |
|
| 1557 | + if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret) |
| 1558 | + port->zero_copy = !!(*(bool *)value); |
| 1559 | + |
1533 | 1560 | return ret;
|
1534 | 1561 | }
|
1535 | 1562 | EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
|
@@ -1698,6 +1725,31 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
|
1698 | 1725 | unsigned long flags = 0;
|
1699 | 1726 | int ret;
|
1700 | 1727 |
|
| 1728 | + /* |
| 1729 | + * We really want to do this in mmal_vchi_buffer_init but can't as |
| 1730 | + * videobuf2 won't let us have the dmabuf there. |
| 1731 | + */ |
| 1732 | + if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) { |
| 1733 | + pr_debug("%s: import dmabuf %p\n", __func__, buffer->dma_buf); |
| 1734 | + ret = vc_sm_cma_import_dmabuf(buffer->dma_buf, |
| 1735 | + &buffer->vcsm_handle); |
| 1736 | + if (ret) { |
| 1737 | + pr_err("%s: vc_sm_import_dmabuf_fd failed, ret %d\n", |
| 1738 | + __func__, ret); |
| 1739 | + return ret; |
| 1740 | + } |
| 1741 | + |
| 1742 | + buffer->vc_handle = vc_sm_cma_int_handle(buffer->vcsm_handle); |
| 1743 | + if (!buffer->vc_handle) { |
| 1744 | + pr_err("%s: vc_sm_int_handle failed %d\n", |
| 1745 | + __func__, ret); |
| 1746 | + vc_sm_cma_free(buffer->vcsm_handle); |
| 1747 | + return ret; |
| 1748 | + } |
| 1749 | + pr_debug("%s: import dmabuf %p - got vc handle %08X\n", |
| 1750 | + __func__, buffer->dma_buf, buffer->vc_handle); |
| 1751 | + } |
| 1752 | + |
1701 | 1753 | ret = buffer_from_host(instance, port, buffer);
|
1702 | 1754 | if (ret == -EINVAL) {
|
1703 | 1755 | /* Port is disabled. Queue for when it is enabled. */
|
@@ -1731,6 +1783,16 @@ int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
|
1731 | 1783 | release_msg_context(msg_context);
|
1732 | 1784 | buf->msg_context = NULL;
|
1733 | 1785 |
|
| 1786 | + if (buf->vcsm_handle) { |
| 1787 | + int ret; |
| 1788 | + |
| 1789 | + pr_debug("%s: vc_sm_cma_free on handle %p\n", __func__, |
| 1790 | + buf->vcsm_handle); |
| 1791 | + ret = vc_sm_cma_free(buf->vcsm_handle); |
| 1792 | + if (ret) |
| 1793 | + pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret); |
| 1794 | + buf->vcsm_handle = 0; |
| 1795 | + } |
1734 | 1796 | return 0;
|
1735 | 1797 | }
|
1736 | 1798 | EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
|
|
0 commit comments