Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c827dab authored by Seemanta Dutta's avatar Seemanta Dutta
Browse files

msm: camera: Add memory manager driver



Add memory manager driver to support different
types of camera buffers.

Different types can include:
  - HW buffers mapped in IOVA space for each HW block
  - Kernel mapped buffers
  - Buffers mapped in user space via mmap()

CRs-Fixed: 1108641
Change-Id: I51c4a02d3646809d7d5fb289e7caae66460577f3
Signed-off-by: default avatarLakshmi Narayana Kalavala <lkalaval@codeaurora.org>
Signed-off-by: default avatarSeemanta Dutta <seemanta@codeaurora.org>
parent 73e234e4
Loading
Loading
Loading
Loading
+130 −0
Original line number Diff line number Diff line
* Qualcomm Technologies, Inc. MSM Camera SMMU

The MSM camera SMMU device provides SMMU context bank definitions
for all HW blocks that need to map IOVA to physical memory. These
definitions consist of various properties that define how the
IOVA address space is laid out for each HW block in the camera
subsystem.

=======================
Required Node Structure
=======================
The camera SMMU device must be described in three levels of device nodes. The
first level describes the overall SMMU device. Within it, second level nodes
describe individual context banks that map different stream ids. There can
also be second level nodes describing firmware device nodes. Each HW block
such as IFE, ICP maps into these second level device nodes. All context bank
specific properties that define how the IOVA is laid out is contained within
third level device nodes within the second level device nodes.

During the kernel initialization all the devices are probed recursively and
a device pointer is created for each context bank keeping track of the IOVA
mapping information.

Duplicate regions of the same type are not allowed within the same
context bank. All context banks must contain an IO region at the very least.

==================================
First Level Node - CAM SMMU device
==================================
- compatible
  Usage: required
  Value type: <string>
  Definition: Should be "qcom,msm-cam-smmu".

===================================================================
Second Level Node - CAM SMMU context bank device or firmware device
===================================================================
- compatible
  Usage: required
  Value type: <string>
  Definition: Should be "qcom,msm-cam-smmu-cb" or "qcom,msm-cam-smmu-fw-dev".

- memory-region
  Usage: optional
  Value type: <phandle>
  Definition: Should specify the phandle of the memory region for firmware.
    allocation

- iommus
  Usage: required
  Value type: <phandle>
  Definition: Should specify the phandle of the iommu sid.

- label
  Usage: required
  Value type: <string>
  Definition: Should specify a string label to identify the context bank.

=============================================
Third Level Node - CAM SMMU memory map device
=============================================
- iova-region-name
  Usage: required
  Value type: <string>
  Definition: Should specify a string label to identify the IOVA region.

- iova-region-start
  Usage: required
  Value type: <u32>
  Definition: Should specify start IOVA for region.

- iova-region-len
  Usage: required
  Value type: <u32>
  Definition: Should specify length for IOVA region.

- iova-region-id
  Usage: required
  Value type: <u32>
  Definition: Should specify the numerical identifier for IOVA region.
    Allowed values are: 0x00 to 0x03
      - Firmware region: 0x00
      - Shared region: 0x01
      - Scratch region: 0x02
      - IO region: 0x03

Example:
	qcom,cam_smmu@0 {
		compatible = "qcom,msm-cam-smmu";

		msm_cam_smmu_icp {
			compatible = "qcom,msm-cam-smmu-cb";
			iommus = <&apps_smmu 0x1078>,
				<&apps_smmu 0x1020>,
				<&apps_smmu 0x1028>,
				<&apps_smmu 0x1040>,
				<&apps_smmu 0x1048>,
				<&apps_smmu 0x1030>,
				<&apps_smmu 0x1050>;
			label = "icp";
			icp_iova_mem_map: iova-mem-map {
				iova-mem-region-firmware {
					/* Firmware region is 5MB */
				        iova-region-name = "firmware";
				        iova-region-start = <0x0>;
				        iova-region-len = <0x500000>;
					iova-region-id = <0x0>;
					status = "ok";
				};

			        iova-mem-region-shared {
					/* Shared region is 100MB long */
				        iova-region-name = "shared";
				        iova-region-start = <0x7400000>;
				        iova-region-len = <0x6400000>;
					iova-region-id = <0x1>;
				        status = "ok";
				};

			        iova-mem-region-io {
				        /* IO region is approximately 3.5 GB */
				        iova-region-name = "io";
					iova-region-start = <0xd800000>;
				        iova-region-len = <0xd2800000>;
				        iova-region-id = <0x3>;
				        status = "ok";
				};
			};
		};
	};
+1 −0
Original line number Diff line number Diff line
@@ -2,3 +2,4 @@ obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_utils/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_core/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_sync/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_smmu/
+3 −1
Original line number Diff line number Diff line
obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr_dev.o cam_req_mgr_util.o cam_req_mgr_core.o  cam_req_mgr_workq.o
ccflags-y += -Idrivers/media/platform/msm/camera/cam_smmu/

obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr_dev.o cam_req_mgr_util.o cam_req_mgr_core.o cam_req_mgr_workq.o cam_mem_mgr.o
+968 −0

File added.

Preview size limit exceeded, changes collapsed.

+121 −0
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only 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.
 */

#ifndef _CAM_MEM_MGR_H_
#define _CAM_MEM_MGR_H_

#include <media/cam_req_mgr.h>
#include "cam_mem_mgr_api.h"

#define CAM_MEM_BUFQ_MAX 1024

/**
 * struct cam_mem_buf_queue
 *
 * @i_hdl:       ion handle for the buffer
 * @q_lock:      mutex lock for buffer
 * @hdls:        list of mapped handles
 * @num_hdl:     number of handles
 * @fd:          file descriptor of buffer
 * @buf_handle:  unique handle for buffer
 * @align:       alignment for allocation
 * @len:         size of buffer
 * @flags:       attributes of buffer
 * @vaddr:       IOVA of buffer
 * @kmdvaddr:    Kernel virtual address
 * @active:      state of the buffer
 * @is_imported: Flag indicating if buffer is imported from an FD in user space
 */
struct cam_mem_buf_queue {
	struct ion_handle *i_hdl;
	struct mutex q_lock;
	int32_t hdls[CAM_MEM_MMU_MAX_HANDLE];
	int32_t num_hdl;
	int32_t fd;
	int32_t buf_handle;
	int32_t align;
	size_t len;
	uint32_t flags;
	uint64_t vaddr;
	uint64_t kmdvaddr;
	bool active;
	bool is_imported;
};

/**
 * struct cam_mem_table
 *
 * @m_lock: mutex lock for table
 * @bitmap: bitmap of the mem mgr utility
 * @bits: max bits of the utility
 * @client: ion client pointer
 * @bufq: array of buffers
 */
struct cam_mem_table {
	struct mutex m_lock;
	void *bitmap;
	size_t bits;
	struct ion_client *client;
	struct cam_mem_buf_queue bufq[CAM_MEM_BUFQ_MAX];
};

/**
 * @brief: Allocates and maps buffer
 *
 * @cmd:   Allocation information
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd);

/**
 * @brief: Releases a buffer reference
 *
 * @cmd:   Buffer release information
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_mem_mgr_release(struct cam_mem_mgr_release_cmd *cmd);

/**
 * @brief Maps a buffer
 *
 * @cmd: Buffer mapping information
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd);

/**
 * @brief: Perform cache ops on the buffer
 *
 * @cmd:   Cache ops information
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_mem_mgr_cache_ops(struct cam_mem_cache_ops_cmd *cmd);

/**
 * @brief: Initializes the memory manager
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_mem_mgr_init(void);

/**
 * @brief:  Tears down the memory manager
 *
 * @return None
 */
void cam_mem_mgr_deinit(void);

#endif /* _CAM_MEM_MGR_H_ */
Loading