Commit 33586072 authored by Dave Stevenson's avatar Dave Stevenson Committed by popcornmix
Browse files

staging: vc04_services: 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 vchiq-mmal.

Signed-off-by: default avatarDave Stevenson <dave.stevenson@raspberrypi.org>
parent efbec169
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ config BCM2835_VCHIQ_MMAL
	tristate "BCM2835 MMAL VCHIQ service"
	depends on (ARCH_BCM2835 || COMPILE_TEST)
	select BCM2835_VCHIQ
	select BCM_VC_SM_CMA
	help
	  Enables the MMAL API over VCHIQ as used for the
	  majority of the multimedia services on VideoCore.
+4 −0
Original line number Diff line number Diff line
@@ -51,6 +51,10 @@ struct mmal_buffer {

	struct mmal_msg_context *msg_context;

	struct dma_buf *dma_buf;/* Exported dmabuf fd from videobuf2 */
	int vcsm_handle;	/* VCSM handle having imported the dmabuf */
	u32 vc_handle;		/* VC handle to that dmabuf */

	u32 cmd;		/* MMAL command. 0=data. */
	unsigned long length;
	u32 mmal_flags;
+64 −2
Original line number Diff line number Diff line
@@ -27,9 +27,12 @@
#include <media/videobuf2-vmalloc.h>

#include "mmal-common.h"
#include "mmal-parameters.h"
#include "mmal-vchiq.h"
#include "mmal-msg.h"

#include "vc-sm-cma/vc_sm_knl.h"

#define USE_VCHIQ_ARM
#include "interface/vchi/vchi.h"

@@ -424,8 +427,13 @@ buffer_from_host(struct vchiq_mmal_instance *instance,

	/* buffer header */
	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 =
			(u32)(unsigned long)buf->buffer;
	}

	m.u.buffer_from_host.buffer_header.alloc_size = buf->buffer_size;
	if (port->type == MMAL_PORT_TYPE_OUTPUT) {
		m.u.buffer_from_host.buffer_header.length = 0;
@@ -590,6 +598,22 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance,

		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) {
		/* empty buffer */
		if (msg->u.buffer_from_host.buffer_header.flags &
@@ -1537,6 +1561,9 @@ int vchiq_mmal_port_parameter_set(struct vchiq_mmal_instance *instance,

	mutex_unlock(&instance->vchiq_mutex);

	if (parameter == MMAL_PARAMETER_ZERO_COPY && !ret)
		port->zero_copy = !!(*(bool *)value);

	return ret;
}
EXPORT_SYMBOL_GPL(vchiq_mmal_port_parameter_set);
@@ -1705,6 +1732,31 @@ int vchiq_mmal_submit_buffer(struct vchiq_mmal_instance *instance,
	unsigned long flags = 0;
	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);
	if (ret == -EINVAL) {
		/* Port is disabled. Queue for when it is enabled. */
@@ -1738,6 +1790,16 @@ int mmal_vchi_buffer_cleanup(struct mmal_buffer *buf)
		release_msg_context(msg_context);
	buf->msg_context = NULL;

	if (buf->vcsm_handle) {
		int ret;

		pr_debug("%s: vc_sm_cma_free on handle %08X\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;
}
EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ typedef void (*vchiq_mmal_buffer_cb)(

struct vchiq_mmal_port {
	u32 enabled:1;
	u32 zero_copy:1;
	u32 handle;
	u32 type; /* port type, cached to use on port info set */
	u32 index; /* port index, cached to use on port info set */