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

Commit 07bc54f4 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: Add new bw voting logic for cpas and its clients"

parents b49960ce a56cd66b
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -271,12 +271,21 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
	if (operation == true) {
		if (!cdm_hw->open_count) {
			struct cam_ahb_vote ahb_vote;
			struct cam_axi_vote axi_vote;
			struct cam_axi_vote axi_vote = {0};

			ahb_vote.type = CAM_VOTE_ABSOLUTE;
			ahb_vote.vote.level = CAM_SVS_VOTE;
			axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
			axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
			axi_vote.num_paths = 1;
			axi_vote.axi_path[0].path_data_type =
				CAM_AXI_PATH_DATA_ALL;
			axi_vote.axi_path[0].transac_type =
				CAM_AXI_TRANSACTION_READ;
			axi_vote.axi_path[0].camnoc_bw =
				CAM_CPAS_DEFAULT_AXI_BW;
			axi_vote.axi_path[0].mnoc_ab_bw =
				CAM_CPAS_DEFAULT_AXI_BW;
			axi_vote.axi_path[0].mnoc_ib_bw =
				CAM_CPAS_DEFAULT_AXI_BW;

			rc = cam_cpas_start(core->cpas_handle,
				&ahb_vote, &axi_vote);
+8 −3
Original line number Diff line number Diff line
@@ -826,7 +826,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
	struct cam_cdm_private_dt_data *soc_private = NULL;
	struct cam_cpas_register_params cpas_parms;
	struct cam_ahb_vote ahb_vote;
	struct cam_axi_vote axi_vote;
	struct cam_axi_vote axi_vote = {0};

	cdm_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
	if (!cdm_hw_intf)
@@ -932,8 +932,13 @@ int cam_hw_cdm_probe(struct platform_device *pdev)

	ahb_vote.type = CAM_VOTE_ABSOLUTE;
	ahb_vote.vote.level = CAM_SVS_VOTE;
	axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
	axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
	axi_vote.num_paths = 1;
	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;
	axi_vote.axi_path[0].camnoc_bw = CAM_CPAS_DEFAULT_AXI_BW;
	axi_vote.axi_path[0].mnoc_ab_bw = CAM_CPAS_DEFAULT_AXI_BW;
	axi_vote.axi_path[0].mnoc_ib_bw = CAM_CPAS_DEFAULT_AXI_BW;

	rc = cam_cpas_start(cdm_core->cpas_handle, &ahb_vote, &axi_vote);
	if (rc) {
		CAM_ERR(CAM_CDM, "CPAS start failed");
+465 −319

File changed.

Preview size limit exceeded, changes collapsed.

+33 −24
Original line number Diff line number Diff line
@@ -6,12 +6,18 @@
#ifndef _CAM_CPAS_HW_H_
#define _CAM_CPAS_HW_H_

#include <dt-bindings/msm/msm-camera.h>
#include "cam_cpas_api.h"
#include "cam_cpas_hw_intf.h"
#include "cam_common_util.h"

#define CAM_CPAS_MAX_CLIENTS 40
#define CAM_CPAS_INFLIGHT_WORKS              5
#define CAM_CPAS_MAX_CLIENTS                 40
#define CAM_CPAS_MAX_AXI_PORTS               6
#define CAM_CPAS_MAX_TREE_LEVELS             4
#define CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT   32
#define CAM_CPAS_PATH_DATA_MAX               38
#define CAM_CPAS_TRANSACTION_MAX             2

#define CAM_CPAS_AXI_MIN_MNOC_AB_BW   (2048 * 1024)
#define CAM_CPAS_AXI_MIN_MNOC_IB_BW   (2048 * 1024)
@@ -25,7 +31,7 @@
	((indx >= 0) && (indx < CAM_CPAS_MAX_CLIENTS))
#define CAM_CPAS_CLIENT_REGISTERED(cpas_core, indx)        \
	((CAM_CPAS_CLIENT_VALID(indx)) && \
	(cpas_core->cpas_client[indx]))
	(cpas_core->cpas_client[indx]->registered))
#define CAM_CPAS_CLIENT_STARTED(cpas_core, indx)          \
	((CAM_CPAS_CLIENT_REGISTERED(cpas_core, indx)) && \
	(cpas_core->cpas_client[indx]->started))
@@ -87,20 +93,25 @@ struct cam_cpas_reg {
 * struct cam_cpas_client : CPAS Client structure info
 *
 * @data: Client register params
 * @registered: Whether client has registered with cpas
 * @started: Whether client has streamed on
 * @tree_node_valid: Indicates whether tree node has at least one valid node
 * @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
 * @tree_node: All granular path voting nodes for the client
 *
 */
struct cam_cpas_client {
	struct cam_cpas_register_params data;
	bool registered;
	bool started;
	bool tree_node_valid;
	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_tree_node *tree_node[CAM_CPAS_PATH_DATA_MAX]
		[CAM_CPAS_TRANSACTION_MAX];
};

/**
@@ -136,30 +147,24 @@ struct cam_cpas_bus_client {
/**
 * 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
 * @lock: Mutex lock for accessing this port
 * @bus_client: bus client info for this port
 * @ib_bw_voting_needed: if this port can update ib bw dynamically
 * @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
 * @consolidated_axi_vote: Consolidated axi bw values for this AXI port
 * @axi_port_node: Node representing AXI Port info in device tree
 * @ab_bw: AB bw value for this port
 * @ib_bw: IB bw value for this port
 * @additional_bw: Additional bandwidth to cover non-hw cpas clients
 */
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 mutex lock;
	struct cam_cpas_bus_client bus_client;
	bool ib_bw_voting_needed;
	struct device_node *axi_port_node;
	struct device_node *axi_port_mnoc_node;
	struct device_node *axi_port_camnoc_node;
	struct cam_axi_vote consolidated_axi_vote;
	uint64_t ab_bw;
	uint64_t ib_bw;
	uint64_t additional_bw;
};

/**
@@ -169,11 +174,12 @@ struct cam_cpas_axi_port {
 * @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
 * @num_axi_ports: Total number of axi ports found in device tree
 * @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
 * @axi_port: AXI port info for a specific axi index
 * @internal_ops: CPAS HW internal ops
 * @work_queue: Work queue handle
 *
@@ -183,11 +189,12 @@ struct cam_cpas {
	struct cam_cpas_client *cpas_client[CAM_CPAS_MAX_CLIENTS];
	struct mutex client_mutex[CAM_CPAS_MAX_CLIENTS];
	uint32_t num_clients;
	uint32_t num_axi_ports;
	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_axi_port axi_port[CAM_CPAS_MAX_AXI_PORTS];
	struct cam_cpas_internal_ops internal_ops;
	struct workqueue_struct *work_queue;
	atomic_t irq_count;
@@ -200,4 +207,6 @@ 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_client_cleanup(struct cam_hw_info *cpas_hw);

#endif /* _CAM_CPAS_HW_H_ */
+72 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/of.h>
@@ -43,6 +43,67 @@ struct cam_cpas_intf {

static struct cam_cpas_intf *g_cpas_intf;

const char *cam_cpas_axi_util_path_type_to_string(
	uint32_t path_data_type)
{
	switch (path_data_type) {
	/* IFE Paths */
	case CAM_AXI_PATH_DATA_IFE_LINEAR:
		return "IFE_LINEAR";
	case CAM_AXI_PATH_DATA_IFE_VID:
		return "IFE_VID";
	case CAM_AXI_PATH_DATA_IFE_DISP:
		return "IFE_DISP";
	case CAM_AXI_PATH_DATA_IFE_STATS:
		return "IFE_STATS";
	case CAM_AXI_PATH_DATA_IFE_RDI0:
		return "IFE_RDI0";
	case CAM_AXI_PATH_DATA_IFE_RDI1:
		return "IFE_RDI1";
	case CAM_AXI_PATH_DATA_IFE_RDI2:
		return "IFE_RDI2";
	case CAM_AXI_PATH_DATA_IFE_RDI3:
		return "IFE_RDI3";
	case CAM_AXI_PATH_DATA_IFE_PDAF:
		return "IFE_PDAF";
	case CAM_AXI_PATH_DATA_IFE_PIXEL_RAW:
		return "IFE_PIXEL_RAW";

	/* IPE Paths */
	case CAM_AXI_PATH_DATA_IPE_RD_IN:
		return "IPE_RD_IN";
	case CAM_AXI_PATH_DATA_IPE_RD_REF:
		return "IPE_RD_REF";
	case CAM_AXI_PATH_DATA_IPE_WR_VID:
		return "IPE_WR_VID";
	case CAM_AXI_PATH_DATA_IPE_WR_DISP:
		return "IPE_WR_DISP";
	case CAM_AXI_PATH_DATA_IPE_WR_REF:
		return "IPE_WR_REF";

	/* Common Paths */
	case CAM_AXI_PATH_DATA_ALL:
		return "DATA_ALL";
	default:
		return "IFE_PATH_INVALID";
	}
}
EXPORT_SYMBOL(cam_cpas_axi_util_path_type_to_string);

const char *cam_cpas_axi_util_trans_type_to_string(
	uint32_t transac_type)
{
	switch (transac_type) {
	case CAM_AXI_TRANSACTION_READ:
		return "TRANSAC_READ";
	case CAM_AXI_TRANSACTION_WRITE:
		return "TRANSAC_WRITE";
	default:
		return "TRANSAC_INVALID";
	}
}
EXPORT_SYMBOL(cam_cpas_axi_util_trans_type_to_string);

int cam_cpas_get_cpas_hw_version(uint32_t *hw_version)
{
	struct cam_hw_info *cpas_hw = NULL;
@@ -69,7 +130,6 @@ int cam_cpas_get_cpas_hw_version(uint32_t *hw_version)
	return 0;
}


int cam_cpas_get_hw_info(uint32_t *camera_family,
	struct cam_hw_version *camera_version,
	struct cam_hw_version *cpas_version,
@@ -184,6 +244,11 @@ int cam_cpas_update_axi_vote(uint32_t client_handle,
		return -ENODEV;
	}

	if (!axi_vote) {
		CAM_ERR(CAM_CPAS, "NULL axi vote");
		return -EINVAL;
	}

	if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
		struct cam_cpas_hw_cmd_axi_vote cmd_axi_vote;

@@ -274,6 +339,11 @@ int cam_cpas_start(uint32_t client_handle,
		return -ENODEV;
	}

	if (!axi_vote) {
		CAM_ERR(CAM_CPAS, "NULL axi vote");
		return -EINVAL;
	}

	if (g_cpas_intf->hw_intf->hw_ops.start) {
		struct cam_cpas_hw_cmd_start cmd_hw_start;

Loading