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

Commit 31d998b2 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 233d0230 on remote branch

Change-Id: I7c61f313c6ffec22bc850f206643387912c535da
parents 90432430 233d0230
Loading
Loading
Loading
Loading
+169 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/types.h>
@@ -715,3 +715,171 @@ void cam_cdm_util_dump_cmd_buf(
		}
	} while (buf_now <= cmd_buf_end);
}

static uint32_t cam_cdm_util_dump_reg_cont_cmd_v2(
	uint32_t                         *cmd_buf_addr,
	struct cam_cdm_cmd_buf_dump_info *dump_info)
{
	int                             i;
	long                            ret;
	uint8_t                        *dst;
	size_t                          remain_len;
	uint32_t                       *temp_ptr = cmd_buf_addr;
	uint32_t                       *addr, *start;
	uint32_t                        min_len;
	struct cdm_regcontinuous_cmd   *p_regcont_cmd;
	struct cam_cdm_cmd_dump_header *hdr;

	p_regcont_cmd = (struct cdm_regcontinuous_cmd *)temp_ptr;
	temp_ptr += cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);
	ret = cdm_get_cmd_header_size(CAM_CDM_CMD_REG_CONT);

	min_len = (sizeof(uint32_t) * p_regcont_cmd->count) +
		sizeof(struct cam_cdm_cmd_dump_header) +
		(2 * sizeof(uint32_t));
	remain_len = dump_info->dst_max_size - dump_info->dst_offset;

	if (remain_len < min_len) {
		CAM_WARN_RATE_LIMIT(CAM_CDM,
			"Dump buffer exhaust remain %zu min %u",
			remain_len, min_len);
		return ret;
	}

	dst = (char *)dump_info->dst_start + dump_info->dst_offset;
	hdr = (struct cam_cdm_cmd_dump_header *)dst;
	scnprintf(hdr->tag, CAM_CDM_CMD_TAG_MAX_LEN, "CDM_REG_CONT:");
	hdr->word_size = sizeof(uint32_t);
	addr = (uint32_t *)(dst + sizeof(struct cam_cdm_cmd_dump_header));
	start = addr;
	*addr++ = p_regcont_cmd->offset;
	*addr++ = p_regcont_cmd->count;
	for (i = 0; i < p_regcont_cmd->count; i++) {
		*addr = *temp_ptr;
		temp_ptr++;
		addr++;
		ret++;
	}
	hdr->size = hdr->word_size * (addr - start);
	dump_info->dst_offset += hdr->size +
		sizeof(struct cam_cdm_cmd_dump_header);

	return ret;
}

static uint32_t cam_cdm_util_dump_reg_random_cmd_v2(
	uint32_t                         *cmd_buf_addr,
	struct cam_cdm_cmd_buf_dump_info *dump_info)
{
	int                             i;
	long                            ret;
	uint8_t                        *dst;
	uint32_t                       *temp_ptr = cmd_buf_addr;
	uint32_t                       *addr, *start;
	size_t                          remain_len;
	uint32_t                        min_len;
	struct cdm_regrandom_cmd       *p_regrand_cmd;
	struct cam_cdm_cmd_dump_header *hdr;

	p_regrand_cmd = (struct cdm_regrandom_cmd *)temp_ptr;
	temp_ptr += cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);
	ret = cdm_get_cmd_header_size(CAM_CDM_CMD_REG_RANDOM);

	min_len = (2 * sizeof(uint32_t) * p_regrand_cmd->count) +
		sizeof(struct cam_cdm_cmd_dump_header) + sizeof(uint32_t);
	remain_len = dump_info->dst_max_size - dump_info->dst_offset;

	if (remain_len < min_len) {
		CAM_WARN_RATE_LIMIT(CAM_CDM,
			"Dump buffer exhaust remain %zu min %u",
			remain_len, min_len);
		return ret;
	}

	dst = (char *)dump_info->dst_start + dump_info->dst_offset;
	hdr = (struct cam_cdm_cmd_dump_header *)dst;
	scnprintf(hdr->tag, CAM_CDM_CMD_TAG_MAX_LEN, "CDM_REG_RANDOM:");
	hdr->word_size = sizeof(uint32_t);
	addr = (uint32_t *)(dst + sizeof(struct cam_cdm_cmd_dump_header));
	start = addr;
	*addr++ = p_regrand_cmd->count;
	for (i = 0; i < p_regrand_cmd->count; i++) {
		addr[0] = temp_ptr[0] & CAM_CDM_REG_OFFSET_MASK;
		addr[1] = temp_ptr[1];
		temp_ptr += 2;
		addr += 2;
		ret += 2;
	}
	hdr->size = hdr->word_size * (addr - start);
	dump_info->dst_offset += hdr->size +
		sizeof(struct cam_cdm_cmd_dump_header);
	return ret;
}

int cam_cdm_util_dump_cmd_bufs_v2(
	struct cam_cdm_cmd_buf_dump_info *dump_info)
{
	uint32_t  cmd;
	uint32_t *buf_now;
	int rc = 0;

	if (!dump_info || !dump_info->src_start || !dump_info->src_end ||
		!dump_info->dst_start) {
		CAM_INFO(CAM_CDM, "Invalid args");
		return -EINVAL;
	}

	buf_now = dump_info->src_start;
	do {
		if (dump_info->dst_offset >= dump_info->dst_max_size) {
			CAM_WARN(CAM_CDM,
				"Dump overshoot offset %zu size %zu",
				dump_info->dst_offset,
				dump_info->dst_max_size);
			return -ENOSPC;
		}
		cmd = *buf_now;
		cmd = cmd >> CAM_CDM_COMMAND_OFFSET;

		switch (cmd) {
		case CAM_CDM_CMD_DMI:
		case CAM_CDM_CMD_DMI_32:
		case CAM_CDM_CMD_DMI_64:
			buf_now += cdm_get_cmd_header_size(CAM_CDM_CMD_DMI);
			break;
		case CAM_CDM_CMD_REG_CONT:
			buf_now += cam_cdm_util_dump_reg_cont_cmd_v2(buf_now,
				dump_info);
			break;
		case CAM_CDM_CMD_REG_RANDOM:
			buf_now += cam_cdm_util_dump_reg_random_cmd_v2(buf_now,
				dump_info);
			break;
		case CAM_CDM_CMD_BUFF_INDIRECT:
			buf_now += cdm_get_cmd_header_size(
				CAM_CDM_CMD_BUFF_INDIRECT);
			break;
		case CAM_CDM_CMD_GEN_IRQ:
			buf_now += cdm_get_cmd_header_size(
				CAM_CDM_CMD_GEN_IRQ);
			break;
		case CAM_CDM_CMD_WAIT_EVENT:
			buf_now += cdm_get_cmd_header_size(
				CAM_CDM_CMD_WAIT_EVENT);
			break;
		case CAM_CDM_CMD_CHANGE_BASE:
			buf_now += cdm_get_cmd_header_size(
				CAM_CDM_CMD_CHANGE_BASE);
			break;
		case CAM_CDM_CMD_PERF_CTRL:
			buf_now += cdm_get_cmd_header_size(
				CAM_CDM_CMD_PERF_CTRL);
			break;
		default:
			CAM_ERR(CAM_CDM, "Invalid CMD: 0x%x", cmd);
			buf_now++;
			break;
		}
	} while (buf_now <= dump_info->src_end);
	return rc;
}
+44 −1
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-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _CAM_CDM_UTIL_H_
#define _CAM_CDM_UTIL_H_

/* Max len for tag name for header while dumping cmd buffer*/
#define CAM_CDM_CMD_TAG_MAX_LEN 32

enum cam_cdm_command {
	CAM_CDM_CMD_UNUSED = 0x0,
	CAM_CDM_CMD_DMI = 0x1,
@@ -144,6 +147,34 @@ void (*cdm_write_genirq)(
	uint32_t  userdata);
};

/**
 * struct cam_cdm_cmd_buf_dump_info; - Camera CDM dump info
 * @dst_offset:      dst offset
 * @dst_max_size     max size of destination buffer
 * @src_start:       source start address
 * @src_end:         source end   address
 * @dst_start:       dst start address
 */
struct cam_cdm_cmd_buf_dump_info {
	size_t    dst_offset;
	size_t    dst_max_size;
	uint32_t *src_start;
	uint32_t *src_end;
	uintptr_t dst_start;
};

/**
 * struct cam_cdm_cmd_dump_header- Camera CDM dump header
 * @tag:       tag name for header
 * @size:      size of data
 * @word_size: size of each word
 */
struct cam_cdm_cmd_dump_header {
	uint8_t   tag[CAM_CDM_CMD_TAG_MAX_LEN];
	uint64_t  size;
	uint32_t  word_size;
};

/**
 * cam_cdm_util_log_cmd_bufs()
 *
@@ -156,6 +187,18 @@ void (*cdm_write_genirq)(
void cam_cdm_util_dump_cmd_buf(
	uint32_t *cmd_buffer_start, uint32_t *cmd_buffer_end);

/**
 * cam_cdm_util_dump_cmd_bufs_v2()
 *
 * @brief:        Util function to cdm command buffers
 *                to a buffer
 *
 * @dump_info:    Information about source and destination buffers
 *
 * return SUCCESS/FAILURE
 */
int cam_cdm_util_dump_cmd_bufs_v2(
	struct cam_cdm_cmd_buf_dump_info *dump_info);


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

#include <linux/device.h>
@@ -242,6 +242,12 @@ static int cam_cpas_util_axi_cleanup(struct cam_cpas *cpas_core,
		return -EINVAL;
	}

	if (cpas_core->num_camnoc_axi_ports > CAM_CPAS_MAX_AXI_PORTS) {
		CAM_ERR(CAM_CPAS, "Invalid num_camnoc_axi_ports: %d",
			cpas_core->num_camnoc_axi_ports);
		return -EINVAL;
	}

	for (i = 0; i < cpas_core->num_axi_ports; i++) {
		cam_cpas_util_unregister_bus_client(
			&cpas_core->axi_port[i].bus_client);
@@ -249,6 +255,13 @@ static int cam_cpas_util_axi_cleanup(struct cam_cpas *cpas_core,
		cpas_core->axi_port[i].axi_port_node = NULL;
	}

	for (i = 0; i < cpas_core->num_camnoc_axi_ports; i++) {
		cam_cpas_util_unregister_bus_client(
			&cpas_core->camnoc_axi_port[i].bus_client);
		of_node_put(cpas_core->camnoc_axi_port[i].axi_port_node);
		cpas_core->camnoc_axi_port[i].axi_port_node = NULL;
	}

	return 0;
}

@@ -257,6 +270,7 @@ static int cam_cpas_util_axi_setup(struct cam_cpas *cpas_core,
{
	int i = 0, rc = 0;
	struct device_node *axi_port_mnoc_node = NULL;
	struct device_node *axi_port_camnoc_node = NULL;

	if (cpas_core->num_axi_ports > CAM_CPAS_MAX_AXI_PORTS) {
		CAM_ERR(CAM_CPAS, "Invalid num_axi_ports: %d",
@@ -271,6 +285,15 @@ static int cam_cpas_util_axi_setup(struct cam_cpas *cpas_core,
		if (rc)
			goto bus_register_fail;
	}
	for (i = 0; i < cpas_core->num_camnoc_axi_ports; i++) {
		axi_port_camnoc_node =
			cpas_core->camnoc_axi_port[i].axi_port_node;
		rc = cam_cpas_util_register_bus_client(soc_info,
			axi_port_camnoc_node,
			&cpas_core->camnoc_axi_port[i].bus_client);
		if (rc)
			goto bus_register_fail;
	}

	return 0;
bus_register_fail:
@@ -608,6 +631,99 @@ static int cam_cpas_axi_consolidate_path_votes(
	return rc;
}

static int cam_cpas_update_axi_vote_bw(
	struct cam_hw_info *cpas_hw,
	struct cam_cpas_tree_node *cpas_tree_node,
	bool   *mnoc_axi_port_updated,
	bool   *camnoc_axi_port_updated)
{
	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
	struct cam_cpas_private_soc *soc_private =
		(struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;

	if (cpas_tree_node->axi_port_idx >= CAM_CPAS_MAX_AXI_PORTS) {
		CAM_ERR(CAM_CPAS, "Invalid axi_port_idx: %d",
			cpas_tree_node->axi_port_idx);
		return -EINVAL;
	}

	cpas_core->axi_port[cpas_tree_node->axi_port_idx].ab_bw =
		cpas_tree_node->mnoc_ab_bw;
	cpas_core->axi_port[cpas_tree_node->axi_port_idx].ib_bw =
		cpas_tree_node->mnoc_ib_bw;
	mnoc_axi_port_updated[cpas_tree_node->axi_port_idx] = true;

	if (soc_private->control_camnoc_axi_clk)
		return 0;

	cpas_core->camnoc_axi_port[cpas_tree_node->axi_port_idx].camnoc_bw =
		cpas_tree_node->camnoc_bw;
	camnoc_axi_port_updated[cpas_tree_node->camnoc_axi_port_idx] = true;
	return 0;
}

static int cam_cpas_camnoc_set_vote_axi_clk_rate(
	struct cam_hw_info *cpas_hw,
	bool   *camnoc_axi_port_updated)
{
	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
	struct cam_cpas_private_soc *soc_private =
		(struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
	int i;
	int rc = 0;
	struct cam_cpas_axi_port *camnoc_axi_port = NULL;
	uint64_t camnoc_bw;

	if (soc_private->control_camnoc_axi_clk) {
		rc = cam_cpas_util_set_camnoc_axi_clk_rate(cpas_hw);
		if (rc)
			CAM_ERR(CAM_CPAS,
				"Failed in setting axi clk rate rc=%d", rc);
		return rc;
	}

	/* Below code is executed if we just vote and do not set the clk rate
	 * for camnoc
	 */

	if (cpas_core->num_camnoc_axi_ports > CAM_CPAS_MAX_AXI_PORTS) {
		CAM_ERR(CAM_CPAS, "Invalid num_camnoc_axi_ports: %d",
			cpas_core->num_camnoc_axi_ports);
		return -EINVAL;
	}

	for (i = 0; i < cpas_core->num_camnoc_axi_ports; i++) {
		if (camnoc_axi_port_updated[i])
			camnoc_axi_port = &cpas_core->camnoc_axi_port[i];
		else
			continue;

		CAM_DBG(CAM_PERF, "Port[%s] : camnoc_bw=%lld",
			camnoc_axi_port->axi_port_name,
			camnoc_axi_port->camnoc_bw);

		if (camnoc_axi_port->camnoc_bw)
			camnoc_bw = camnoc_axi_port->camnoc_bw;
		else
			camnoc_bw = camnoc_axi_port->additional_bw;

		rc = cam_cpas_util_vote_bus_client_bw(
			&camnoc_axi_port->bus_client,
			0, camnoc_bw, true);

		CAM_DBG(CAM_CPAS,
			"camnoc vote camnoc_bw[%llu] rc=%d %s",
			camnoc_bw, rc, camnoc_axi_port->axi_port_name);
		if (rc) {
			CAM_ERR(CAM_CPAS,
				"Failed in camnoc vote camnoc_bw[%llu] rc=%d",
				camnoc_bw, rc);
			break;
		}
	}
	return rc;
}

static int cam_cpas_util_apply_client_axi_vote(
	struct cam_hw_info *cpas_hw,
	struct cam_cpas_client *cpas_client,
@@ -615,12 +731,13 @@ static int cam_cpas_util_apply_client_axi_vote(
{
	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
	struct cam_axi_vote *con_axi_vote = NULL;
	struct cam_cpas_axi_port *axi_port = NULL;
	struct cam_cpas_axi_port *mnoc_axi_port = NULL;
	struct cam_cpas_tree_node *curr_tree_node = NULL;
	struct cam_cpas_tree_node *par_tree_node = NULL;
	uint32_t transac_type;
	uint32_t path_data_type;
	bool axi_port_updated[CAM_CPAS_MAX_AXI_PORTS] = {false};
	bool mnoc_axi_port_updated[CAM_CPAS_MAX_AXI_PORTS] = {false};
	bool camnoc_axi_port_updated[CAM_CPAS_MAX_AXI_PORTS] = {false};
	uint64_t mnoc_ab_bw = 0, mnoc_ib_bw = 0,
		curr_camnoc_old = 0, curr_mnoc_ab_old = 0, curr_mnoc_ib_old = 0,
		par_camnoc_old = 0, par_mnoc_ab_old = 0, par_mnoc_ib_old = 0;
@@ -643,7 +760,7 @@ static int cam_cpas_util_apply_client_axi_vote(
				cpas_core->axi_port[i].additional_bw -=
					CAM_CPAS_DEFAULT_AXI_BW;
			}
			axi_port_updated[i] = true;
			mnoc_axi_port_updated[i] = true;
		}
		goto vote_start_clients;
	}
@@ -733,15 +850,15 @@ static int cam_cpas_util_apply_client_axi_vote(
					rc = -EINVAL;
					goto unlock_tree;
				}

				cpas_core->axi_port
				[par_tree_node->axi_port_idx].ab_bw =
				par_tree_node->mnoc_ab_bw;
				cpas_core->axi_port
				[par_tree_node->axi_port_idx].ib_bw =
				par_tree_node->mnoc_ib_bw;
				axi_port_updated[par_tree_node->axi_port_idx] =
					true;
				rc = cam_cpas_update_axi_vote_bw(cpas_hw,
					par_tree_node,
					mnoc_axi_port_updated,
					camnoc_axi_port_updated);
				if (rc) {
					CAM_ERR(CAM_CPAS,
						"Update Vote failed");
					goto unlock_tree;
				}
			}

			curr_tree_node = par_tree_node;
@@ -759,26 +876,27 @@ static int cam_cpas_util_apply_client_axi_vote(

vote_start_clients:
	for (i = 0; i < cpas_core->num_axi_ports; i++) {
		if (axi_port_updated[i])
			axi_port = &cpas_core->axi_port[i];
		if (mnoc_axi_port_updated[i])
			mnoc_axi_port = &cpas_core->axi_port[i];
		else
			continue;

		CAM_DBG(CAM_PERF, "Port[%s] : ab=%lld ib=%lld additional=%lld",
			axi_port->axi_port_name, axi_port->ab_bw,
			axi_port->ib_bw, axi_port->additional_bw);
			mnoc_axi_port->axi_port_name, mnoc_axi_port->ab_bw,
			mnoc_axi_port->ib_bw, mnoc_axi_port->additional_bw);

		if (axi_port->ab_bw)
			mnoc_ab_bw = axi_port->ab_bw;
		if (mnoc_axi_port->ab_bw)
			mnoc_ab_bw = mnoc_axi_port->ab_bw;
		else
			mnoc_ab_bw = axi_port->additional_bw;
			mnoc_ab_bw = mnoc_axi_port->additional_bw;

		if (cpas_core->axi_port[i].ib_bw_voting_needed)
			mnoc_ib_bw = axi_port->ib_bw;
			mnoc_ib_bw = mnoc_axi_port->ib_bw;
		else
			mnoc_ib_bw = 0;

		rc = cam_cpas_util_vote_bus_client_bw(&axi_port->bus_client,
		rc = cam_cpas_util_vote_bus_client_bw(
			&mnoc_axi_port->bus_client,
			mnoc_ab_bw, mnoc_ib_bw, false);
		if (rc) {
			CAM_ERR(CAM_CPAS,
@@ -787,8 +905,8 @@ static int cam_cpas_util_apply_client_axi_vote(
			goto unlock_tree;
		}
	}

	rc = cam_cpas_util_set_camnoc_axi_clk_rate(cpas_hw);
	rc = cam_cpas_camnoc_set_vote_axi_clk_rate(
		cpas_hw, camnoc_axi_port_updated);
	if (rc)
		CAM_ERR(CAM_CPAS, "Failed in setting axi clk rate rc=%d", rc);

+7 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _CAM_CPAS_HW_H_
@@ -153,6 +153,7 @@ struct cam_cpas_bus_client {
 * @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
 * @camnoc_bw: CAMNOC bw value for this port
 * @additional_bw: Additional bandwidth to cover non-hw cpas clients
 */
struct cam_cpas_axi_port {
@@ -162,6 +163,7 @@ struct cam_cpas_axi_port {
	struct device_node *axi_port_node;
	uint64_t ab_bw;
	uint64_t ib_bw;
	uint64_t camnoc_bw;
	uint64_t additional_bw;
};

@@ -174,11 +176,13 @@ struct cam_cpas_axi_port {
 * @tree_lock: Mutex lock for accessing CPAS node tree
 * @num_clients: Total number of clients that CPAS supports
 * @num_axi_ports: Total number of axi ports found in device tree
 * @num_camnoc_axi_ports: Total number of camnoc 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_port: AXI port info for a specific axi index
 * @camnoc_axi_port: CAMNOC AXI port info for a specific camnoc axi index
 * @internal_ops: CPAS HW internal ops
 * @work_queue: Work queue handle
 * @irq_count: atomic irq count
@@ -193,11 +197,13 @@ struct cam_cpas {
	struct mutex tree_lock;
	uint32_t num_clients;
	uint32_t num_axi_ports;
	uint32_t num_camnoc_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 cam_cpas_axi_port axi_port[CAM_CPAS_MAX_AXI_PORTS];
	struct cam_cpas_axi_port camnoc_axi_port[CAM_CPAS_MAX_AXI_PORTS];
	struct cam_cpas_internal_ops internal_ops;
	struct workqueue_struct *work_queue;
	atomic_t irq_count;
+54 −2
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/device.h>
@@ -134,6 +134,47 @@ static int cam_cpas_util_path_type_to_idx(uint32_t *path_data_type)
	return 0;
}

static int cam_cpas_update_camnoc_node(struct cam_cpas *cpas_core,
	struct device_node *curr_node,
	struct cam_cpas_tree_node *cpas_node_ptr,
	int *camnoc_idx)

{
	struct device_node *camnoc_node;
	int rc;

	camnoc_node = of_find_node_by_name(curr_node,
			"qcom,axi-port-camnoc");
	if (camnoc_node) {

		if (*camnoc_idx >=
			CAM_CPAS_MAX_AXI_PORTS) {
			CAM_ERR(CAM_CPAS, "CAMNOC axi index overshoot %d",
				*camnoc_idx);
			return -EINVAL;
		}

		cpas_core->camnoc_axi_port[*camnoc_idx]
			.axi_port_node = camnoc_node;
		rc = of_property_read_string(
			curr_node,
			"qcom,axi-port-name",
			&cpas_core->camnoc_axi_port[*camnoc_idx]
			.axi_port_name);

		if (rc) {
			CAM_ERR(CAM_CPAS,
				"fail to read camnoc-port-name rc=%d",
				rc);
			return rc;
		}
		cpas_node_ptr->camnoc_axi_port_idx = *camnoc_idx;
		cpas_core->num_camnoc_axi_ports++;
		(*camnoc_idx)++;
	}
	return 0;
}

static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
	struct device_node *of_node, struct cam_cpas_private_soc *soc_private)
{
@@ -142,7 +183,7 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
	struct device_node *curr_node;
	struct device_node *parent_node;
	struct device_node *mnoc_node;
	int mnoc_idx = 0;
	int mnoc_idx = 0, camnoc_idx = 0;
	uint32_t path_idx;
	bool camnoc_max_needed = false;
	struct cam_cpas_tree_node *curr_node_ptr = NULL;
@@ -248,6 +289,17 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
				cpas_core->num_axi_ports++;
			}

			if (!soc_private->control_camnoc_axi_clk) {
				rc = cam_cpas_update_camnoc_node(
					cpas_core, curr_node, curr_node_ptr,
					&camnoc_idx);
				if (rc) {
					CAM_ERR(CAM_CPAS,
						"Parse Camnoc port fail");
					return rc;
				}
			}

			rc = of_property_read_string(curr_node,
				"client-name", &client_name);
			if (!rc) {
Loading