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

Commit 76678e9b authored by Pavan Kumar Chilamkurthi's avatar Pavan Kumar Chilamkurthi Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: Add driver for CPAS core



Enable CPAS(Camera Peripheral And System) driver
to perform CPAS HW functionality and mechanism to
perform AHB and AXI bus bandwidth voting.

CRs-Fixed: 2019539
Change-Id: Ifee9b18848ddc6db510059bf547be32943da2dbc
Signed-off-by: default avatarPavan Kumar Chilamkurthi <pchilamk@codeaurora.org>
parent deda3be7
Loading
Loading
Loading
Loading
+282 −0
Original line number Diff line number Diff line
* Qualcomm Technologies, Inc. MSM Camera CPAS

The MSM camera CPAS device provides dependency definitions for
enabling Camera CPAS HW and provides the Client definitions
for all HW blocks that use CPAS driver for BW voting. These
definitions consist of various properties that define the list
of clients supported, AHB, AXI master-slave IDs used for BW
voting.

=======================
Required Node Structure
=======================
The camera CPAS device must be described in four levels of device nodes. The
first level describes the overall CPAS device. Within it, second level nodes
describe the list of AXI ports that map different clients for AXI BW voting.
Third level nodes describe the details of each AXI port having name, mnoc,
camnoc AXI Bus information. Fourth level nodes describe the details of Bus
master-slave IDs, ab, ib values for mnoc, camnoc bus interface.

==================================
First Level Node - CAM CPAS device
==================================
- cell-index
  Usage: required
  Value type: <u32>
  Definition: Node instance number.

- compatible
  Usage: required
  Value type: <string>
  Definition: Should be "qcom,cam-cpas".

- label
  Usage: required
  Value type: <string>
  Definition: Should be "cpas".

- arch-compat
  Usage: required
  Value type: <string>
  Definition: Should be "cpas_top" or "camss_top".

- reg-names
  Usage: required
  Value type: <string>
  Definition: Name of the register resources.

- reg
  Usage: required
  Value type: <u32>
  Definition: Register values.

- reg-cam-base
  Usage: required
  Value type: <u32>
  Definition: Offset of the register space compared to
              to Camera base register space.

- interrupt-names
  Usage: optional
  Value type: <string>
  Definition: Name of the interrupt.

- interrupts
  Usage: optional
  Value type: <u32>
  Definition: Interrupt associated with CAMNOC HW.

- regulator-names
  Usage: required
  Value type: <string>
  Definition: Name of the regulator resources for CPAS HW.

- camss-vdd-supply
  Usage: required
  Value type: <phandle>
  Definition: Regulator reference corresponding to the names listed
              in "regulator-names".

- clock-names
  Usage: required
  Value type: <string>
  Definition: List of clock names required for CPAS HW.

- clocks
  Usage: required
  Value type: <phandle>
  Definition: List of clocks used for CPAS HW.

- src-clock-name
  Usage: required
  Value type: <string>
  Definition: Source clock name.

- clock-rates
  Usage: required
  Value type: <u32>
  Definition: List of clocks rates.

- qcom,msm-bus,name
- qcom,msm-bus,num-cases
- qcom,msm-bus,num-paths
- qcom,msm-bus,vectors-KBps
  Please refer Documentation/devicetree/bindings/arm/msm/msm_bus.txt
  for the properties above.

- client-id-based
  Usage: required
  Value type: <empty>
  Definition: Bool property specifying whether CPAS clients are ID based.

- client-names
  Usage: required
  Value type: <string>
  Definition: List of Clients supported by CPAS.

- client-axi-port-names
  Usage: required
  Value type: <string>
  Definition: AXI Port name for each client.

- client-bus-camnoc-based
  Usage: required
  Value type: <empty>
  Definition: Bool property specifying whether Clients are connected
              through CAMNOC for AXI access.

===================================================================
Third Level Node - CAM AXI Port properties
===================================================================
- qcom,axi-port-name
  Usage: required
  Value type: <string>
  Definition: Name of the AXI Port.

===================================================================
Fourth Level Node - CAM AXI Bus properties
===================================================================

- qcom,msm-bus,name
- qcom,msm-bus,num-cases
- qcom,msm-bus,num-paths
- qcom,msm-bus,vectors-KBps
  Please refer Documentation/devicetree/bindings/arm/msm/msm_bus.txt
  for the properties above.

- qcom,msm-bus-vector-dyn-vote
  Usage: optional
  Value type: <empty>
  Definition: Bool property specifying whether this bus client
              is dynamic vote based.

Example:

	qcom,cam-cpas@ac40000 {
		cell-index = <0>;
		compatible = "qcom,cam-cpas";
		label = "cpas";
		arch-compat = "cpas_top";
		status = "ok";
		reg-names = "cam_cpas_top", "cam_camnoc";
		reg = <0xac40000 0x1000>,
			<0xac42000 0x5000>;
		reg-cam-base = <0x40000 0x42000>;
		interrupt-names = "cpas_camnoc";
		interrupts = <0 459 0>;
		regulator-names = "camss-vdd";
		camss-vdd-supply = <&titan_top_gdsc>;
		clock-names = "gcc_ahb_clk",
			"gcc_axi_clk",
			"soc_ahb_clk",
			"cpas_ahb_clk",
			"slow_ahb_clk_src",
			"camnoc_axi_clk";
		clocks = <&clock_gcc GCC_CAMERA_AHB_CLK>,
			<&clock_gcc GCC_CAMERA_AXI_CLK>,
			<&clock_camcc CAM_CC_SOC_AHB_CLK>,
			<&clock_camcc CAM_CC_CPAS_AHB_CLK>,
			<&clock_camcc CAM_CC_SLOW_AHB_CLK_SRC>,
			<&clock_camcc CAM_CC_CAMNOC_AXI_CLK>;
		src-clock-name = "slow_ahb_clk_src";
		clock-rates = <0 0 0 0 80000000 0>;
		qcom,msm-bus,name = "cam_ahb";
		qcom,msm-bus,num-cases = <4>;
		qcom,msm-bus,num-paths = <1>;
		qcom,msm-bus,vectors-KBps =
			<MSM_BUS_MASTER_AMPSS_M0
			MSM_BUS_SLAVE_CAMERA_CFG 0 0>,
			<MSM_BUS_MASTER_AMPSS_M0
			MSM_BUS_SLAVE_CAMERA_CFG 0 300000>,
			<MSM_BUS_MASTER_AMPSS_M0
			MSM_BUS_SLAVE_CAMERA_CFG 0 640000>,
			<MSM_BUS_MASTER_AMPSS_M0
			MSM_BUS_SLAVE_CAMERA_CFG 0 640000>;
		client-id-based;
		client-names =
			"ife0", "ife1", "ife2", "ipe0",
			"ipe1", "cam-cdm-intf0", "cpas-cdm0", "bps0",
			"icp0", "jpeg-dma0", "jpeg0", "fd0";
		client-axi-port-names =
			"cam_hf_1", "cam_hf_2", "cam_hf_2", "cam_sf_1",
			"cam_sf_1", "cam_sf_1", "cam_sf_1", "cam_sf_1",
			"cam_sf_1", "cam_sf_1", "cam_sf_1", "cam_sf_1";
		client-bus-camnoc-based;
		qcom,axi-port-list {
			qcom,axi-port1 {
				qcom,axi-port-name = "cam_hf_1";
				qcom,axi-port-mnoc {
					qcom,msm-bus,name = "cam_hf_1_mnoc";
					qcom,msm-bus-vector-dyn-vote;
					qcom,msm-bus,num-cases = <2>;
					qcom,msm-bus,num-paths = <1>;
					qcom,msm-bus,vectors-KBps =
						<MSM_BUS_MASTER_CAMNOC_HF
						MSM_BUS_SLAVE_EBI_CH0 0 0>,
						<MSM_BUS_MASTER_CAMNOC_HF
						MSM_BUS_SLAVE_EBI_CH0 0 0>;
				};
				qcom,axi-port-camnoc {
					qcom,msm-bus,name = "cam_hf_1_camnoc";
					qcom,msm-bus-vector-dyn-vote;
					qcom,msm-bus,num-cases = <2>;
					qcom,msm-bus,num-paths = <1>;
					qcom,msm-bus,vectors-KBps =
						<MSM_BUS_MASTER_CAMNOC_HF
						MSM_BUS_SLAVE_EBI_CH0 0 0>,
						<MSM_BUS_MASTER_CAMNOC_HF
						MSM_BUS_SLAVE_EBI_CH0 0 0>;
				};
			};
			qcom,axi-port2 {
				qcom,axi-port-name = "cam_hf_2";
				qcom,axi-port-mnoc {
					qcom,msm-bus,name = "cam_hf_2_mnoc";
					qcom,msm-bus-vector-dyn-vote;
					qcom,msm-bus,num-cases = <2>;
					qcom,msm-bus,num-paths = <1>;
					qcom,msm-bus,vectors-KBps =
						<MSM_BUS_MASTER_CAMNOC_HF
						MSM_BUS_SLAVE_EBI_CH0 0 0>,
						<MSM_BUS_MASTER_CAMNOC_HF
						MSM_BUS_SLAVE_EBI_CH0 0 0>;
				};
				qcom,axi-port-camnoc {
					qcom,msm-bus,name = "cam_hf_1_camnoc";
					qcom,msm-bus-vector-dyn-vote;
					qcom,msm-bus,num-cases = <2>;
					qcom,msm-bus,num-paths = <1>;
					qcom,msm-bus,vectors-KBps =
						<MSM_BUS_MASTER_CAMNOC_HF
						MSM_BUS_SLAVE_EBI_CH0 0 0>,
						<MSM_BUS_MASTER_CAMNOC_HF
						MSM_BUS_SLAVE_EBI_CH0 0 0>;
				};
			};
			qcom,axi-port3 {
				qcom,axi-port-name = "cam_sf_1";
				qcom,axi-port-mnoc {
					qcom,msm-bus,name = "cam_sf_1_mnoc";
					qcom,msm-bus-vector-dyn-vote;
					qcom,msm-bus,num-cases = <2>;
					qcom,msm-bus,num-paths = <1>;
					qcom,msm-bus,vectors-KBps =
						<MSM_BUS_MASTER_CAMNOC_SF
						MSM_BUS_SLAVE_EBI_CH0 0 0>,
						<MSM_BUS_MASTER_CAMNOC_SF
						MSM_BUS_SLAVE_EBI_CH0 0 0>;
				};
				qcom,axi-port-camnoc {
					qcom,msm-bus,name = "cam_sf_1_camnoc";
					qcom,msm-bus-vector-dyn-vote;
					qcom,msm-bus,num-cases = <2>;
					qcom,msm-bus,num-paths = <1>;
					qcom,msm-bus,vectors-KBps =
						<MSM_BUS_MASTER_CAMNOC_SF
						MSM_BUS_SLAVE_EBI_CH0 0 0>,
						<MSM_BUS_MASTER_CAMNOC_SF
						MSM_BUS_SLAVE_EBI_CH0 0 0>;
				};
			};
		};
	};
+1 −0
Original line number Diff line number Diff line
@@ -3,3 +3,4 @@ obj-$(CONFIG_SPECTRA_CAMERA) += cam_utils/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_core/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_sync/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_smmu/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_cpas/
+10 −0
Original line number Diff line number Diff line
ccflags-y += -Idrivers/media/platform/msm/camera/cam_utils
ccflags-y += -Idrivers/media/platform/msm/camera/cam_req_mgr
ccflags-y += -Idrivers/media/platform/msm/camera/cam_core
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/include
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/cpas_top
ccflags-y += -Idrivers/media/platform/msm/camera/cam_cpas/camss_top

obj-$(CONFIG_SPECTRA_CAMERA) += cpas_top/
obj-$(CONFIG_SPECTRA_CAMERA) += camss_top/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_cpas_soc.o cam_cpas_intf.o cam_cpas_hw.o
 No newline at end of file
+1415 −0

File added.

Preview size limit exceeded, changes collapsed.

+193 −0
Original line number Diff line number Diff line
/* Copyright (c) 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_CPAS_HW_H_
#define _CAM_CPAS_HW_H_

#include "cam_cpas_api.h"
#include "cam_cpas_hw_intf.h"

#define CPAS_MAX_CLIENTS 20

#define CAM_CPAS_GET_CLIENT_IDX(handle) (handle)
#define CAM_CPAS_GET_CLIENT_HANDLE(indx) (indx)

#define CAM_CPAS_CLIENT_VALID(indx) ((indx >= 0) && (indx < CPAS_MAX_CLIENTS))
#define CAM_CPAS_CLIENT_REGISTERED(cpas_core, indx)        \
	((CAM_CPAS_CLIENT_VALID(indx)) && \
	(cpas_core->cpas_client[indx]))
#define CAM_CPAS_CLIENT_STARTED(cpas_core, indx)          \
	((CAM_CPAS_CLIENT_REGISTERED(cpas_core, indx)) && \
	(cpas_core->cpas_client[indx]->started))

/**
 * enum cam_cpas_access_type - Enum for Register access type
 */
enum cam_cpas_access_type {
	CAM_REG_TYPE_READ,
	CAM_REG_TYPE_WRITE,
	CAM_REG_TYPE_READ_WRITE,
};

/**
 * struct cam_cpas_internal_ops - CPAS Hardware layer internal ops
 *
 * @get_hw_info: Function pointer for get hw info
 * @init_hw_version: Function pointer for hw init based on version
 * @handle_irq: Function poniter for irq handling
 * @setup_regbase: Function pointer for setup rebase indices
 * @power_on_settings: Function pointer for hw core specific power on settings
 *
 */
struct cam_cpas_internal_ops {
	int (*get_hw_info)(struct cam_hw_info *cpas_hw,
		struct cam_cpas_hw_caps *hw_caps);
	int (*init_hw_version)(struct cam_hw_info *cpas_hw,
		struct cam_cpas_hw_caps *hw_caps);
	irqreturn_t (*handle_irq)(int irq_num, void *data);
	int (*setup_regbase)(struct cam_hw_soc_info *soc_info,
		int32_t regbase_index[], int32_t num_reg_map);
	int (*power_on_settings)(struct cam_hw_info *cpas_hw);
};

/**
 * struct cam_cpas_reg : CPAS register info
 *
 * @enable: Whether this reg info need to be enabled
 * @access_type: Register access type
 * @masked_value: Whether this register write/read is based on mask, shift
 * @mask: Mask for this register value
 * @shift: Shift for this register value
 * @value: Register value
 *
 */
struct cam_cpas_reg {
	bool enable;
	enum cam_cpas_access_type access_type;
	bool masked_value;
	uint32_t offset;
	uint32_t mask;
	uint32_t shift;
	uint32_t value;
};

/**
 * struct cam_cpas_client : CPAS Client structure info
 *
 * @data: Client register params
 * @started: Whether client has streamed on
 * @ahb_level: Determined/Applied ahb level for the client
 * @axi_vote: Determined/Applied axi vote for the client
 * @axi_port: Client's parent axi port
 * @axi_sibling_client: Client's sibllings sharing the same axi port
 *
 */
struct cam_cpas_client {
	struct cam_cpas_register_params data;
	bool started;
	enum cam_vote_level ahb_level;
	struct cam_axi_vote axi_vote;
	struct cam_cpas_axi_port *axi_port;
	struct list_head axi_sibling_client;
};

/**
 * struct cam_cpas_bus_client : Bus client information
 *
 * @src: Bus master/src id
 * @dst: Bus slave/dst id
 * @pdata: Bus pdata information
 * @client_id: Bus client id
 * @num_usecases: Number of use cases for this client
 * @num_paths: Number of paths for this client
 * @curr_vote_level: current voted index
 * @dyn_vote: Whether dynamic voting enabled
 * @lock: Mutex lock used while voting on this client
 * @valid: Whether bus client is valid
 *
 */
struct cam_cpas_bus_client {
	int src;
	int dst;
	struct msm_bus_scale_pdata *pdata;
	uint32_t client_id;
	int num_usecases;
	int num_paths;
	unsigned int curr_vote_level;
	bool dyn_vote;
	struct mutex lock;
	bool valid;
};

/**
 * struct cam_cpas_axi_port : AXI port information
 *
 * @sibling_port: Sibling AXI ports
 * @clients_list_head: List head pointing to list of clients sharing this port
 * @lock: Mutex lock for accessing this port
 * @camnoc_bus: CAMNOC bus client info for this port
 * @mnoc_bus: MNOC bus client info for this port
 * @axi_port_name: Name of this AXI port
 * @axi_port_node: Node representing this AXI Port
 * @axi_port_mnoc_node: Node representing mnoc in this AXI Port
 * @axi_port_camnoc_node: Node representing camnoc in this AXI Port
 *
 */
struct cam_cpas_axi_port {
	struct list_head sibling_port;
	struct list_head clients_list_head;
	struct mutex lock;
	struct cam_cpas_bus_client camnoc_bus;
	struct cam_cpas_bus_client mnoc_bus;
	const char *axi_port_name;
	struct device_node *axi_port_node;
	struct device_node *axi_port_mnoc_node;
	struct device_node *axi_port_camnoc_node;
};

/**
 * struct cam_cpas : CPAS core data structure info
 *
 * @hw_caps: CPAS hw capabilities
 * @cpas_client: Array of pointers to CPAS clients info
 * @client_mutex: Mutex for accessing client info
 * @num_clients: Total number of clients that CPAS supports
 * @registered_clients: Number of Clients registered currently
 * @streamon_clients: Number of Clients that are in start state currently
 * @regbase_index: Register base indices for CPAS register base IDs
 * @ahb_bus_client: AHB Bus client info
 * @axi_ports_list_head: Head pointing to list of AXI ports
 * @internal_ops: CPAS HW internal ops
 *
 */
struct cam_cpas {
	struct cam_cpas_hw_caps hw_caps;
	struct cam_cpas_client *cpas_client[CPAS_MAX_CLIENTS];
	struct mutex client_mutex[CPAS_MAX_CLIENTS];
	uint32_t num_clients;
	uint32_t registered_clients;
	uint32_t streamon_clients;
	int32_t regbase_index[CAM_CPAS_REG_MAX];
	struct cam_cpas_bus_client ahb_bus_client;
	struct list_head axi_ports_list_head;
	struct cam_cpas_internal_ops internal_ops;
};

int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops);
int cam_cpastop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops);

int cam_cpas_util_reg_update(struct cam_hw_info *cpas_hw,
	enum cam_cpas_reg_base reg_base, struct cam_cpas_reg *reg_info);
int cam_cpas_util_get_string_index(const char **strings,
	uint32_t num_strings, char *matching_string, uint32_t *index);

#endif /* _CAM_CPAS_HW_H_ */
Loading