From patchwork Fri Jul 17 00:15:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 8836 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id F3E61C2E7A for ; Fri, 17 Jul 2020 00:15:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 188E5610D5; Fri, 17 Jul 2020 02:15:35 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Jsx3kSLt"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7D12C6049C for ; Fri, 17 Jul 2020 02:15:33 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 09FCC514; Fri, 17 Jul 2020 02:15:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1594944933; bh=3czI3WomyfKNhFm2lRe50/F2N7rOoDfKpomWSWJORpI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Jsx3kSLtfgwUv7Xdr7J6dm+q15F3HzF5sZI7mtmFSCOtn31bqSxyrlwGmdK9wevEi aEpUBXHt1Wsv9Wdfi9kRJRdFoiPwbAYvFgiPhjD9dXKPvPmEgmNq9ep2teDi4YbkYC mWVWKEj1L/sKKRTCMOlID55QZp7qYn8FbIdEwKkM= From: Laurent Pinchart To: Naushir Patuck Date: Fri, 17 Jul 2020 03:15:17 +0300 Message-Id: <20200717001518.20285-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200717001518.20285-1-laurent.pinchart@ideasonboard.com> References: <20200717001518.20285-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/2] include: linux: Add dma-buf.h and dma-heap.h UAPI headers X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libcamera-devel@lists.libcamera.org Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck This commit adds the dmabuf UAPI headers from the mainline Linux kernel v5.6.19. They are required by the Raspberry Pi library for lens shading table allocations. Signed-off-by: Naushir Patuck Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart --- include/linux/dma-buf.h | 50 +++++++++++++++++++++++++++++++++++++ include/linux/dma-heap.h | 53 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 include/linux/dma-buf.h create mode 100644 include/linux/dma-heap.h diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h new file mode 100644 index 000000000000..7f30393b92c3 --- /dev/null +++ b/include/linux/dma-buf.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Framework for buffer objects that can be shared across devices/subsystems. + * + * Copyright(C) 2015 Intel Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef _DMA_BUF_UAPI_H_ +#define _DMA_BUF_UAPI_H_ + +#include + +/* begin/end dma-buf functions used for userspace mmap. */ +struct dma_buf_sync { + __u64 flags; +}; + +#define DMA_BUF_SYNC_READ (1 << 0) +#define DMA_BUF_SYNC_WRITE (2 << 0) +#define DMA_BUF_SYNC_RW (DMA_BUF_SYNC_READ | DMA_BUF_SYNC_WRITE) +#define DMA_BUF_SYNC_START (0 << 2) +#define DMA_BUF_SYNC_END (1 << 2) +#define DMA_BUF_SYNC_VALID_FLAGS_MASK \ + (DMA_BUF_SYNC_RW | DMA_BUF_SYNC_END) + +#define DMA_BUF_NAME_LEN 32 + +#define DMA_BUF_BASE 'b' +#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) + +/* 32/64bitness of this uapi was botched in android, there's no difference + * between them in actual uapi, they're just different numbers. + */ +#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *) +#define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32) +#define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64) + +#endif diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h new file mode 100644 index 000000000000..6f84fa08e074 --- /dev/null +++ b/include/linux/dma-heap.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * DMABUF Heaps Userspace API + * + * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2019 Linaro Ltd. + */ +#ifndef _UAPI_LINUX_DMABUF_POOL_H +#define _UAPI_LINUX_DMABUF_POOL_H + +#include +#include + +/** + * DOC: DMABUF Heaps Userspace API + */ + +/* Valid FD_FLAGS are O_CLOEXEC, O_RDONLY, O_WRONLY, O_RDWR */ +#define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE) + +/* Currently no heap flags */ +#define DMA_HEAP_VALID_HEAP_FLAGS (0) + +/** + * struct dma_heap_allocation_data - metadata passed from userspace for + * allocations + * @len: size of the allocation + * @fd: will be populated with a fd which provides the + * handle to the allocated dma-buf + * @fd_flags: file descriptor flags used when allocating + * @heap_flags: flags passed to heap + * + * Provided by userspace as an argument to the ioctl + */ +struct dma_heap_allocation_data { + __u64 len; + __u32 fd; + __u32 fd_flags; + __u64 heap_flags; +}; + +#define DMA_HEAP_IOC_MAGIC 'H' + +/** + * DOC: DMA_HEAP_IOCTL_ALLOC - allocate memory from pool + * + * Takes a dma_heap_allocation_data struct and returns it with the fd field + * populated with the dmabuf handle of the allocation. + */ +#define DMA_HEAP_IOCTL_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,\ + struct dma_heap_allocation_data) + +#endif /* _UAPI_LINUX_DMABUF_POOL_H */ From patchwork Fri Jul 17 00:15:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 8837 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id ED226C2E7A for ; Fri, 17 Jul 2020 00:15:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B52C760561; Fri, 17 Jul 2020 02:15:36 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="fPl8CiwI"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F3E3C60498 for ; Fri, 17 Jul 2020 02:15:33 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi [81.175.216.236]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 60043A5E; Fri, 17 Jul 2020 02:15:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1594944933; bh=jqj7FKaWRPODsP9WpewpmbeZLEQTFRcnerLekhFCooo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fPl8CiwIwyJWxGs5lszpAGEmV/dkYekM3d/5DM7JhP9u56qeZhokzoyeAgmC2L2We KIcwFxFbmhrxC/uwe8Y6s9PP/zsmlm8jadQoHXzgRvajOxzo8VUxDWWQ78yKqz4VTj 7zwWoEfJaGWTpnHekJdxNnUXaNDQnWGL0fsy+mNU= From: Laurent Pinchart To: Naushir Patuck Date: Fri, 17 Jul 2020 03:15:18 +0300 Message-Id: <20200717001518.20285-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200717001518.20285-1-laurent.pinchart@ideasonboard.com> References: <20200717001518.20285-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/2] libcamera: pipeline: ipa: raspberrypi: Use dma heap allocs for LS tables X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libcamera-devel@lists.libcamera.org Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Naushir Patuck Remove use of vcsm allocations and replace with dma heap allocations. The pipeline handler now passes the fd of the allocation over to the IPA instead of the raw pointer. Also use libcamera::FileDescriptor for fd lifetime management. This commit must be built alongside the accompanying BCM2835 ISP kernel driver changes at https://github.com/raspberrypi/linux/pull/3715. Otherwise a mismatch will cause undefined behavior. Signed-off-by: Naushir Patuck Reviewed-by: Laurent Pinchart Signed-off-by: Laurent Pinchart Reviewed-by: Naushir Patuck --- include/linux/bcm2835-isp.h | 4 +- include/linux/vc_sm_cma_ioctl.h | 135 ---------------- src/ipa/raspberrypi/raspberrypi.cpp | 28 +++- .../pipeline/raspberrypi/dma_heaps.cpp | 84 ++++++++++ .../pipeline/raspberrypi/dma_heaps.h | 31 ++++ .../pipeline/raspberrypi/meson.build | 1 + .../pipeline/raspberrypi/raspberrypi.cpp | 49 ++---- src/libcamera/pipeline/raspberrypi/vcsm.h | 149 ------------------ 8 files changed, 154 insertions(+), 327 deletions(-) delete mode 100644 include/linux/vc_sm_cma_ioctl.h create mode 100644 src/libcamera/pipeline/raspberrypi/dma_heaps.cpp create mode 100644 src/libcamera/pipeline/raspberrypi/dma_heaps.h delete mode 100644 src/libcamera/pipeline/raspberrypi/vcsm.h diff --git a/include/linux/bcm2835-isp.h b/include/linux/bcm2835-isp.h index e7afc367fd76..45abb681517e 100644 --- a/include/linux/bcm2835-isp.h +++ b/include/linux/bcm2835-isp.h @@ -108,7 +108,7 @@ enum bcm2835_isp_gain_format { * @grid_stride: Row to row distance (in grid cells) between grid cells * in the same horizontal location. * @grid_height: Height of lens shading tables in grid cells. - * @mem_handle_table: Memory handle to the tables. + * @dmabuf: dmabuf file handle containing the table. * @ref_transform: Reference transform - unsupported, please pass zero. * @corner_sampled: Whether the gains are sampled at the corner points * of the grid cells or in the cell centres. @@ -120,7 +120,7 @@ struct bcm2835_isp_lens_shading { __u32 grid_width; __u32 grid_stride; __u32 grid_height; - __u32 mem_handle_table; + __s32 dmabuf; __u32 ref_transform; __u32 corner_sampled; __u32 gain_format; diff --git a/include/linux/vc_sm_cma_ioctl.h b/include/linux/vc_sm_cma_ioctl.h deleted file mode 100644 index 21b8758ea03f..000000000000 --- a/include/linux/vc_sm_cma_ioctl.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright (c) 2012, Broadcom Europe Ltd -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * Copyright 2019 Raspberry Pi (Trading) Ltd. All rights reserved. - * - * Based on vmcs_sm_ioctl.h Copyright Broadcom Corporation. - */ - -#ifndef __VC_SM_CMA_IOCTL_H -#define __VC_SM_CMA_IOCTL_H - -/* ---- Include Files ---------------------------------------------------- */ - -#include /* Needed for standard types */ - -#include - -/* ---- Constants and Types ---------------------------------------------- */ - -#define VC_SM_CMA_RESOURCE_NAME 32 -#define VC_SM_CMA_RESOURCE_NAME_DEFAULT "sm-host-resource" - -/* Type define used to create unique IOCTL number */ -#define VC_SM_CMA_MAGIC_TYPE 'J' - -/* IOCTL commands on /dev/vc-sm-cma */ -enum vc_sm_cma_cmd_e { - VC_SM_CMA_CMD_ALLOC = 0x5A, /* Start at 0x5A arbitrarily */ - - VC_SM_CMA_CMD_IMPORT_DMABUF, - - VC_SM_CMA_CMD_CLEAN_INVALID2, - - VC_SM_CMA_CMD_LAST /* Do not delete */ -}; - -/* Cache type supported, conveniently matches the user space definition in - * user-vcsm.h. - */ -enum vc_sm_cma_cache_e { - VC_SM_CMA_CACHE_NONE, - VC_SM_CMA_CACHE_HOST, - VC_SM_CMA_CACHE_VC, - VC_SM_CMA_CACHE_BOTH, -}; - -/* IOCTL Data structures */ -struct vc_sm_cma_ioctl_alloc { - /* user -> kernel */ - __u32 size; - __u32 num; - __u32 cached; /* enum vc_sm_cma_cache_e */ - __u32 pad; - __u8 name[VC_SM_CMA_RESOURCE_NAME]; - - /* kernel -> user */ - __s32 handle; - __u32 vc_handle; - __u64 dma_addr; -}; - -struct vc_sm_cma_ioctl_import_dmabuf { - /* user -> kernel */ - __s32 dmabuf_fd; - __u32 cached; /* enum vc_sm_cma_cache_e */ - __u8 name[VC_SM_CMA_RESOURCE_NAME]; - - /* kernel -> user */ - __s32 handle; - __u32 vc_handle; - __u32 size; - __u32 pad; - __u64 dma_addr; -}; - -/* - * Cache functions to be set to struct vc_sm_cma_ioctl_clean_invalid2 - * invalidate_mode. - */ -#define VC_SM_CACHE_OP_NOP 0x00 -#define VC_SM_CACHE_OP_INV 0x01 -#define VC_SM_CACHE_OP_CLEAN 0x02 -#define VC_SM_CACHE_OP_FLUSH 0x03 - -struct vc_sm_cma_ioctl_clean_invalid2 { - __u32 op_count; - __u32 pad; - struct vc_sm_cma_ioctl_clean_invalid_block { - __u32 invalidate_mode; - __u32 block_count; - void * /*__user */start_address; - __u32 block_size; - __u32 inter_block_stride; - } s[0]; -}; - -/* IOCTL numbers */ -#define VC_SM_CMA_IOCTL_MEM_ALLOC\ - _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_ALLOC,\ - struct vc_sm_cma_ioctl_alloc) - -#define VC_SM_CMA_IOCTL_MEM_IMPORT_DMABUF\ - _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_IMPORT_DMABUF,\ - struct vc_sm_cma_ioctl_import_dmabuf) - -#define VC_SM_CMA_IOCTL_MEM_CLEAN_INVALID2\ - _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_CLEAN_INVALID2,\ - struct vc_sm_cma_ioctl_clean_invalid2) - -#endif /* __VC_SM_CMA_IOCTL_H */ diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 2fcbc782f8b8..7bd0488089e8 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -65,12 +66,14 @@ public: IPARPi() : lastMode_({}), controller_(), controllerInit_(false), frame_count_(0), check_count_(0), hide_count_(0), - mistrust_count_(0), lsTableHandle_(0), lsTable_(nullptr) + mistrust_count_(0), lsTable_(nullptr) { } ~IPARPi() { + if (lsTable_) + munmap(lsTable_, MAX_LS_GRID_SIZE); } int init(const IPASettings &settings) override; @@ -139,7 +142,7 @@ private: /* How many frames we should avoid running control algos on. */ unsigned int mistrust_count_; /* LS table allocation passed in from the pipeline handler. */ - uint32_t lsTableHandle_; + FileDescriptor lsTableHandle_; void *lsTable_; }; @@ -280,8 +283,23 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, /* Store the lens shading table pointer and handle if available. */ if (ipaConfig.operation & RPI_IPA_CONFIG_LS_TABLE) { - lsTable_ = reinterpret_cast(ipaConfig.data[0]); - lsTableHandle_ = ipaConfig.data[1]; + /* Remove any previous table, if there was one. */ + if (lsTable_) { + munmap(lsTable_, MAX_LS_GRID_SIZE); + lsTable_ = nullptr; + } + + /* Map the LS table buffer into user space. */ + lsTableHandle_ = FileDescriptor(ipaConfig.data[0]); + if (lsTableHandle_.isValid()) { + lsTable_ = mmap(nullptr, MAX_LS_GRID_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, lsTableHandle_.fd(), 0); + + if (lsTable_ == MAP_FAILED) { + LOG(IPARPI, Error) << "dmaHeap mmap failure for LS table."; + lsTable_ = nullptr; + } + } } } @@ -1030,7 +1048,7 @@ void IPARPi::applyLS(const struct AlscStatus *lsStatus, ControlList &ctrls) .grid_width = w, .grid_stride = w, .grid_height = h, - .mem_handle_table = lsTableHandle_, + .dmabuf = lsTableHandle_.fd(), .ref_transform = 0, .corner_sampled = 1, .gain_format = GAIN_FORMAT_U4P10 diff --git a/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp new file mode 100644 index 000000000000..6769c04640f1 --- /dev/null +++ b/src/libcamera/pipeline/raspberrypi/dma_heaps.cpp @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Raspberry Pi (Trading) Limited + * + * dma_heaps.h - Helper class for dma-heap allocations. + */ + +#include "dma_heaps.h" + +#include +#include +#include +#include +#include + +#include "libcamera/internal/log.h" + +/* + * /dev/dma-heap/linux,cma is the dma-heap allocator, which allows dmaheap-cma + * to only have to worry about importing. + * + * Annoyingly, should the cma heap size be specified on the kernel command line + * instead of DT, the heap gets named "reserved" instead. + */ +#define DMA_HEAP_CMA_NAME "/dev/dma_heap/linux,cma" +#define DMA_HEAP_CMA_ALT_NAME "/dev/dma_heap/reserved" + +namespace libcamera { + +LOG_DECLARE_CATEGORY(RPI) + +namespace RPi { + +DmaHeap::DmaHeap() +{ + dmaHeapHandle_ = ::open(DMA_HEAP_CMA_NAME, O_RDWR, 0); + if (dmaHeapHandle_ == -1) { + dmaHeapHandle_ = ::open(DMA_HEAP_CMA_ALT_NAME, O_RDWR, 0); + if (dmaHeapHandle_ == -1) { + LOG(RPI, Error) << "Could not open dmaHeap device"; + } + } +} + +DmaHeap::~DmaHeap() +{ + if (dmaHeapHandle_) + ::close(dmaHeapHandle_); +} + +FileDescriptor DmaHeap::alloc(const char *name, std::size_t size) +{ + int ret; + + if (!name) + return FileDescriptor(); + + struct dma_heap_allocation_data alloc = {}; + + alloc.len = size; + alloc.fd_flags = O_CLOEXEC | O_RDWR; + + ret = ::ioctl(dmaHeapHandle_, DMA_HEAP_IOCTL_ALLOC, &alloc); + + if (ret < 0) { + LOG(RPI, Error) << "dmaHeap allocation failure for " + << name; + return FileDescriptor(); + } + + ret = ::ioctl(alloc.fd, DMA_BUF_SET_NAME, name); + if (ret < 0) { + LOG(RPI, Error) << "dmaHeap naming failure for " + << name; + ::close(alloc.fd); + return FileDescriptor(); + } + + return FileDescriptor(std::move(alloc.fd)); +} + +} /* namespace RPi */ + +} /* namespace libcamera */ diff --git a/src/libcamera/pipeline/raspberrypi/dma_heaps.h b/src/libcamera/pipeline/raspberrypi/dma_heaps.h new file mode 100644 index 000000000000..ae6be1135f17 --- /dev/null +++ b/src/libcamera/pipeline/raspberrypi/dma_heaps.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Raspberry Pi (Trading) Limited + * + * dma_heaps.h - Helper class for dma-heap allocations. + */ +#ifndef __LIBCAMERA_PIPELINE_RASPBERRYPI_DMA_HEAPS_H__ +#define __LIBCAMERA_PIPELINE_RASPBERRYPI_DMA_HEAPS_H__ + +#include + +namespace libcamera { + +namespace RPi { + +class DmaHeap +{ +public: + DmaHeap(); + ~DmaHeap(); + FileDescriptor alloc(const char *name, std::size_t size); + +private: + int dmaHeapHandle_; +}; + +} /* namespace RPi */ + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_PIPELINE_RASPBERRYPI_DMA_HEAPS_H__ */ diff --git a/src/libcamera/pipeline/raspberrypi/meson.build b/src/libcamera/pipeline/raspberrypi/meson.build index dcfe07c5b720..ae0aed3b5234 100644 --- a/src/libcamera/pipeline/raspberrypi/meson.build +++ b/src/libcamera/pipeline/raspberrypi/meson.build @@ -1,6 +1,7 @@ # SPDX-License-Identifier: CC0-1.0 libcamera_sources += files([ + 'dma_heaps.cpp', 'raspberrypi.cpp', 'staggered_ctrl.cpp', ]) diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 718749af5a6e..bf1c77144f85 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -31,8 +32,8 @@ #include "libcamera/internal/v4l2_controls.h" #include "libcamera/internal/v4l2_videodevice.h" +#include "dma_heaps.h" #include "staggered_ctrl.h" -#include "vcsm.h" namespace libcamera { @@ -286,24 +287,11 @@ class RPiCameraData : public CameraData { public: RPiCameraData(PipelineHandler *pipe) - : CameraData(pipe), sensor_(nullptr), lsTable_(nullptr), - state_(State::Stopped), dropFrame_(false), ispOutputCount_(0) + : CameraData(pipe), sensor_(nullptr), state_(State::Stopped), + dropFrame_(false), ispOutputCount_(0) { } - ~RPiCameraData() - { - /* - * Free the LS table if we have allocated one. Another - * allocation will occur in applyLS() with the appropriate - * size. - */ - if (lsTable_) { - vcsm_.free(lsTable_); - lsTable_ = nullptr; - } - } - void frameStarted(uint32_t sequence); int loadIPA(); @@ -329,9 +317,9 @@ public: /* Buffers passed to the IPA. */ std::vector ipaBuffers_; - /* VCSM allocation helper. */ - ::RPi::Vcsm vcsm_; - void *lsTable_; + /* DMAHEAP allocation helper. */ + RPi::DmaHeap dmaHeap_; + FileDescriptor lsTable_; RPi::StaggeredCtrl staggeredCtrl_; uint32_t expectedSequence_; @@ -1142,26 +1130,15 @@ int RPiCameraData::configureIPA() entityControls.emplace(0, unicam_[Unicam::Image].dev()->controls()); entityControls.emplace(1, isp_[Isp::Input].dev()->controls()); - /* Allocate the lens shading table via vcsm and pass to the IPA. */ - if (!lsTable_) { - lsTable_ = vcsm_.alloc("ls_grid", MAX_LS_GRID_SIZE); - uintptr_t ptr = reinterpret_cast(lsTable_); - - if (!lsTable_) + /* Allocate the lens shading table via dmaHeap and pass to the IPA. */ + if (!lsTable_.isValid()) { + lsTable_ = dmaHeap_.alloc("ls_grid", MAX_LS_GRID_SIZE); + if (!lsTable_.isValid()) return -ENOMEM; - /* - * The vcsm allocation will always be in the memory region - * < 32-bits to allow Videocore to access the memory. - * - * \todo Sending a pointer to the IPA is a workaround for - * vc_sm_cma not yet supporting dmabuf. This will not work with - * IPA module isolation and should be reworked when vc_sma_cma - * will permit. - */ + /* Allow the IPA to mmap the LS table via the file descriptor. */ ipaConfig.operation = RPI_IPA_CONFIG_LS_TABLE; - ipaConfig.data = { static_cast(ptr & 0xffffffff), - vcsm_.getVCHandle(lsTable_) }; + ipaConfig.data = { static_cast(lsTable_.fd()) }; } CameraSensorInfo sensorInfo = {}; diff --git a/src/libcamera/pipeline/raspberrypi/vcsm.h b/src/libcamera/pipeline/raspberrypi/vcsm.h deleted file mode 100644 index bebe86a76450..000000000000 --- a/src/libcamera/pipeline/raspberrypi/vcsm.h +++ /dev/null @@ -1,149 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2019, Raspberry Pi (Trading) Limited - * - * vcsm.h - Helper class for vcsm allocations. - */ -#ifndef __LIBCAMERA_PIPELINE_RASPBERRYPI_VCSM_H__ -#define __LIBCAMERA_PIPELINE_RASPBERRYPI_VCSM_H__ - -#include -#include - -#include -#include -#include -#include -#include - -namespace RPi { - -#define VCSM_CMA_DEVICE_NAME "/dev/vcsm-cma" - -class Vcsm -{ -public: - Vcsm() - { - vcsmHandle_ = ::open(VCSM_CMA_DEVICE_NAME, O_RDWR, 0); - if (vcsmHandle_ == -1) { - std::cerr << "Could not open vcsm device: " - << VCSM_CMA_DEVICE_NAME; - } - } - - ~Vcsm() - { - /* Free all existing allocations. */ - auto it = allocMap_.begin(); - while (it != allocMap_.end()) - it = remove(it->first); - - if (vcsmHandle_) - ::close(vcsmHandle_); - } - - void *alloc(const char *name, unsigned int size, - vc_sm_cma_cache_e cache = VC_SM_CMA_CACHE_NONE) - { - unsigned int pageSize = getpagesize(); - void *user_ptr; - int ret; - - if (!name) - return nullptr; - - /* Ask for page aligned allocation. */ - size = (size + pageSize - 1) & ~(pageSize - 1); - - struct vc_sm_cma_ioctl_alloc alloc; - memset(&alloc, 0, sizeof(alloc)); - alloc.size = size; - alloc.num = 1; - alloc.cached = cache; - alloc.handle = 0; - memcpy(alloc.name, name, 32); - - ret = ::ioctl(vcsmHandle_, VC_SM_CMA_IOCTL_MEM_ALLOC, &alloc); - - if (ret < 0 || alloc.handle < 0) { - std::cerr << "vcsm allocation failure for " - << name << std::endl; - return nullptr; - } - - /* Map the buffer into user space. */ - user_ptr = ::mmap(0, alloc.size, PROT_READ | PROT_WRITE, - MAP_SHARED, alloc.handle, 0); - - if (user_ptr == MAP_FAILED) { - std::cerr << "vcsm mmap failure for " << name << std::endl; - ::close(alloc.handle); - return nullptr; - } - - std::lock_guard lock(lock_); - allocMap_.emplace(user_ptr, AllocInfo(alloc.handle, - alloc.size, alloc.vc_handle)); - - return user_ptr; - } - - void free(void *user_ptr) - { - std::lock_guard lock(lock_); - remove(user_ptr); - } - - unsigned int getVCHandle(void *user_ptr) - { - std::lock_guard lock(lock_); - auto it = allocMap_.find(user_ptr); - if (it != allocMap_.end()) - return it->second.vcHandle; - - return 0; - } - -private: - struct AllocInfo { - AllocInfo(int handle_, int size_, int vcHandle_) - : handle(handle_), size(size_), vcHandle(vcHandle_) - { - } - - int handle; - int size; - uint32_t vcHandle; - }; - - /* Map of all allocations that have been requested. */ - using AllocMap = std::map; - - AllocMap::iterator remove(void *user_ptr) - { - auto it = allocMap_.find(user_ptr); - if (it != allocMap_.end()) { - int handle = it->second.handle; - int size = it->second.size; - ::munmap(user_ptr, size); - ::close(handle); - /* - * Remove the allocation from the map. This returns - * an iterator to the next element. - */ - it = allocMap_.erase(it); - } - - /* Returns an iterator to the next element. */ - return it; - } - - AllocMap allocMap_; - int vcsmHandle_; - std::mutex lock_; -}; - -} /* namespace RPi */ - -#endif /* __LIBCAMERA_PIPELINE_RASPBERRYPI_VCSM_H__ */