lkml.org 
[lkml]   [2022]   [Nov]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 05/14] staging: mmal-vchiq: Use vc-sm-cma to support zero copy
    Date
    From: Dave Stevenson <dave.stevenson@raspberrypi.com>

    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>
    Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
    ---
    .../staging/vc04_services/vchiq-mmal/Kconfig | 1 +
    .../vc04_services/vchiq-mmal/mmal-common.h | 4 +
    .../vc04_services/vchiq-mmal/mmal-vchiq.c | 83 +++++++++++++++++--
    .../vc04_services/vchiq-mmal/mmal-vchiq.h | 1 +
    4 files changed, 82 insertions(+), 7 deletions(-)

    diff --git a/drivers/staging/vc04_services/vchiq-mmal/Kconfig b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
    index c99525a0bb45..a7c1a7bf516e 100644
    --- a/drivers/staging/vc04_services/vchiq-mmal/Kconfig
    +++ b/drivers/staging/vc04_services/vchiq-mmal/Kconfig
    @@ -1,6 +1,7 @@
    config BCM2835_VCHIQ_MMAL
    tristate "BCM2835 MMAL VCHIQ service"
    depends on BCM2835_VCHIQ
    + select BCM_VC_SM_CMA
    help
    Enables the MMAL API over VCHIQ interface as used for the
    majority of the multimedia services on VideoCore.
    diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
    index 0443be8198ea..a643cad54b12 100644
    --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
    +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
    @@ -50,6 +50,10 @@ struct mmal_buffer {

    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. */
    unsigned long length;
    u32 mmal_flags;
    diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
    index 1c0047eead7e..f26fb64a2785 100644
    --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
    +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
    @@ -27,9 +27,11 @@
    #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"
    /*
    * maximum number of components supported.
    * This matches the maximum permitted by default on the VPU
    @@ -416,14 +418,27 @@ buffer_from_host(struct vchiq_mmal_instance *instance,

    /* buffer header */
    m.u.buffer_from_host.buffer_header.cmd = 0;
    - m.u.buffer_from_host.buffer_header.data =
    - (u32)(unsigned long)buf->buffer;
    + 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;
    - m.u.buffer_from_host.buffer_header.length = 0; /* nothing used yet */
    - m.u.buffer_from_host.buffer_header.offset = 0; /* no offset */
    - m.u.buffer_from_host.buffer_header.flags = 0; /* no flags */
    - m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN;
    - m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN;
    + if (port->type == MMAL_PORT_TYPE_OUTPUT) {
    + m.u.buffer_from_host.buffer_header.length = 0;
    + m.u.buffer_from_host.buffer_header.offset = 0;
    + m.u.buffer_from_host.buffer_header.flags = 0;
    + m.u.buffer_from_host.buffer_header.pts = MMAL_TIME_UNKNOWN;
    + m.u.buffer_from_host.buffer_header.dts = MMAL_TIME_UNKNOWN;
    + } else {
    + m.u.buffer_from_host.buffer_header.length = buf->length;
    + m.u.buffer_from_host.buffer_header.offset = 0;
    + m.u.buffer_from_host.buffer_header.flags = buf->mmal_flags;
    + m.u.buffer_from_host.buffer_header.pts = buf->pts;
    + m.u.buffer_from_host.buffer_header.dts = buf->dts;
    + }

    /* clear buffer type specific data */
    memset(&m.u.buffer_from_host.buffer_header_type_specific, 0,
    @@ -575,6 +590,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 &
    @@ -1520,6 +1551,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);
    @@ -1688,6 +1722,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. */
    @@ -1721,6 +1780,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 %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;
    }
    EXPORT_SYMBOL_GPL(mmal_vchi_buffer_cleanup);
    diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
    index e3ecd70b9951..9addd627ff5b 100644
    --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
    +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
    @@ -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 */
    --
    2.37.3
    \
     
     \ /
      Last update: 2022-11-21 22:50    [W:4.369 / U:0.176 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site