staging: mmal-vchiq: Use vc-sm-cma to support zero copy

With the vc-sm-cma driver we can support zero copy of buffers between
the kernel and VPU. Add this support to mmal-vchiq.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>

vc-sm-cma: fixed kbuild problem

error logs:
  drivers/staging/vc04_services/vc-sm-cma/Kconfig:1:error: recursive dependency detected!
  drivers/staging/vc04_services/vc-sm-cma/Kconfig:1:      symbol BCM_VC_SM_CMA is selected by BCM2835_VCHIQ_MMAL
  drivers/staging/vc04_services/vchiq-mmal/Kconfig:1:     symbol BCM2835_VCHIQ_MMAL depends on BCM2835_VCHIQ
  drivers/staging/vc04_services/Kconfig:14:       symbol BCM2835_VCHIQ is selected by BCM_VC_SM_CMA
  For a resolution refer to Documentation/kbuild/kconfig-language.rst
  subsection "Kconfig recursive dependency limitations"

Tested-by: make ARCH=arm64 bcm2711_defconfig
Test platform: fedora 33
Branch: rpi-5.10.y
This commit is contained in:
Dave Stevenson
2018-09-25 16:07:55 +01:00
committed by Dom Cobley
parent ea2434dbbc
commit 201a57438a
4 changed files with 71 additions and 3 deletions

View File

@@ -1,6 +1,7 @@
config BCM2835_VCHIQ_MMAL config BCM2835_VCHIQ_MMAL
tristate "BCM2835 MMAL VCHIQ service" tristate "BCM2835 MMAL VCHIQ service"
depends on BCM2835_VCHIQ select BCM2835_VCHIQ
select BCM_VC_SM_CMA
help help
Enables the MMAL API over VCHIQ interface as used for the Enables the MMAL API over VCHIQ interface as used for the
majority of the multimedia services on VideoCore. majority of the multimedia services on VideoCore.

View File

@@ -50,6 +50,10 @@ struct mmal_buffer {
struct mmal_msg_context *msg_context; struct mmal_msg_context *msg_context;
struct dma_buf *dma_buf;/* Exported dmabuf fd from videobuf2 */
void *vcsm_handle; /* VCSM handle having imported the dmabuf */
u32 vc_handle; /* VC handle to that dmabuf */
u32 cmd; /* MMAL command. 0=data. */ u32 cmd; /* MMAL command. 0=data. */
unsigned long length; unsigned long length;
u32 mmal_flags; u32 mmal_flags;

View File

@@ -27,9 +27,12 @@
#include "../include/linux/raspberrypi/vchiq.h" #include "../include/linux/raspberrypi/vchiq.h"
#include "mmal-common.h" #include "mmal-common.h"
#include "mmal-parameters.h"
#include "mmal-vchiq.h" #include "mmal-vchiq.h"
#include "mmal-msg.h" #include "mmal-msg.h"
#include "../vc-sm-cma/vc_sm_knl.h"
/* /*
* maximum number of components supported. * maximum number of components supported.
* This matches the maximum permitted by default on the VPU * This matches the maximum permitted by default on the VPU
@@ -416,8 +419,13 @@ buffer_from_host(struct vchiq_mmal_instance *instance,
/* buffer header */ /* buffer header */
m.u.buffer_from_host.buffer_header.cmd = 0; m.u.buffer_from_host.buffer_header.cmd = 0;
if (port->zero_copy) {
m.u.buffer_from_host.buffer_header.data = buf->vc_handle;
} else {
m.u.buffer_from_host.buffer_header.data = m.u.buffer_from_host.buffer_header.data =
(u32)(unsigned long)buf->buffer; (u32)(unsigned long)buf->buffer;
}
m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size; m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
if (port->type == MMAL_PORT_TYPE_OUTPUT) { if (port->type == MMAL_PORT_TYPE_OUTPUT) {
m.u.buffer_from_host.buffer_header.length = 0; m.u.buffer_from_host.buffer_header.length = 0;
@@ -583,6 +591,22 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance,
msg_context->u.bulk.status = msg->h.status; msg_context->u.bulk.status = msg->h.status;
} else if (msg->u.buffer_from_host.is_zero_copy) {
/*
* Zero copy buffer, so nothing to do.
* Copy buffer info and make callback.
*/
msg_context->u.bulk.buffer_used =
msg->u.buffer_from_host.buffer_header.length;
msg_context->u.bulk.mmal_flags =
msg->u.buffer_from_host.buffer_header.flags;
msg_context->u.bulk.dts =
msg->u.buffer_from_host.buffer_header.dts;
msg_context->u.bulk.pts =
msg->u.buffer_from_host.buffer_header.pts;
msg_context->u.bulk.cmd =
msg->u.buffer_from_host.buffer_header.cmd;
} else if (msg->u.buffer_from_host.buffer_header.length == 0) { } else if (msg->u.buffer_from_host.buffer_header.length == 0) {
/* empty buffer */ /* empty buffer */
if (msg->u.buffer_from_host.buffer_header.flags & if (msg->u.buffer_from_host.buffer_header.flags &
@@ -1528,6 +1552,9 @@ int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,
mutex_unlock(&instance->vchiq_mutex); mutex_unlock(&instance->vchiq_mutex);
if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret)
port->zero_copy = !!(*(bool *)value);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set); EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
@@ -1696,6 +1723,31 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
unsigned long flags = 0; unsigned long flags = 0;
int ret; int ret;
/*
* We really want to do this in mmal_vchi_buffer_init but can't as
* videobuf2 won't let us have the dmabuf there.
*/
if (port->zero_copy && buffer->dma_buf && !buffer->vcsm_handle) {
pr_debug("%s: import dmabuf %p\n", __func__, buffer->dma_buf);
ret = vc_sm_cma_import_dmabuf(buffer->dma_buf,
&buffer->vcsm_handle);
if (ret) {
pr_err("%s: vc_sm_import_dmabuf_fd failed, ret %d\n",
__func__, ret);
return ret;
}
buffer->vc_handle = vc_sm_cma_int_handle(buffer->vcsm_handle);
if (!buffer->vc_handle) {
pr_err("%s: vc_sm_int_handle failed %d\n",
__func__, ret);
vc_sm_cma_free(buffer->vcsm_handle);
return ret;
}
pr_debug("%s: import dmabuf %p - got vc handle %08X\n",
__func__, buffer->dma_buf, buffer->vc_handle);
}
ret = buffer_from_host(instance, port, buffer); ret = buffer_from_host(instance, port, buffer);
if (ret == -EINVAL) { if (ret == -EINVAL) {
/* Port is disabled. Queue for when it is enabled. */ /* Port is disabled. Queue for when it is enabled. */
@@ -1729,6 +1781,16 @@ int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
release_msg_context(msg_context); release_msg_context(msg_context);
buf->msg_context = NULL; buf->msg_context = NULL;
if (buf->vcsm_handle) {
int ret;
pr_debug("%s: vc_sm_cma_free on handle %p\n", __func__,
buf->vcsm_handle);
ret = vc_sm_cma_free(buf->vcsm_handle);
if (ret)
pr_err("%s: vcsm_free failed, ret %d\n", __func__, ret);
buf->vcsm_handle = 0;
}
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup); EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);

View File

@@ -49,6 +49,7 @@ typedef void (*vchiq_mmal_buffer_cb)(
struct vchiq_mmal_port { struct vchiq_mmal_port {
bool enabled; bool enabled;
u32 zero_copy:1;
u32 handle; u32 handle;
u32 type; /* port type, cached to use on port info set */ u32 type; /* port type, cached to use on port info set */
u32 index; /* port index, cached to use on port info set */ u32 index; /* port index, cached to use on port info set */