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

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

Merge a63af807 on remote branch

Change-Id: I66339172962b3f9d49b60cbe4ab0085f656b1b80
parents 31d998b2 a63af807
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "cam_cdm_soc.h"
#include "cam_io_util.h"
#include "cam_hw_cdm170_reg.h"
#include "cam_trace.h"

#define CAM_HW_CDM_CPAS_0_NAME "qcom,cam170-cpas-cdm0"
#define CAM_HW_CDM_IPE_0_NAME "qcom,cam170-ipe0-cdm"
@@ -380,6 +381,8 @@ int cam_hw_cdm_submit_gen_irq(struct cam_hw_info *cdm_hw,
		rc = -EIO;
	}

	trace_cam_log_event("CDM_START", "CDM_START_IRQ", req->data->cookie, 0);

end:
	return rc;
}
@@ -679,6 +682,9 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
					"Failed to read CDM HW IRQ data");
			}
		}
		trace_cam_log_event("CDM_DONE", "CDM_DONE_IRQ",
			payload->irq_status,
			cdm_hw->soc_info.index);
		CAM_DBG(CAM_CDM, "Got payload=%d", payload->irq_status);
		payload->hw = cdm_hw;
		INIT_WORK((struct work_struct *)&payload->work,
+3 −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/slab.h>
@@ -268,6 +268,7 @@ int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
		return -EINVAL;
	}

	mutex_lock(&ctx->ctx_mutex);
	if ((ctx->state > CAM_CTX_AVAILABLE) &&
		(ctx->state < CAM_CTX_STATE_MAX)) {
		if (ctx->state_machine[ctx->state].pagefault_ops) {
@@ -278,6 +279,7 @@ int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
				ctx->dev_hdl, ctx->state);
		}
	}
	mutex_unlock(&ctx->ctx_mutex);

	return rc;
}
+8 −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/debugfs.h>
@@ -296,6 +296,13 @@ int32_t cam_context_config_dev_to_hw(
		return rc;
	}

	if ((len < sizeof(struct cam_packet)) ||
		(cmd->offset >= (len - sizeof(struct cam_packet)))) {
		CAM_ERR(CAM_CTXT, "Not enough buf, len : %zu offset = %llu",
			len, cmd->offset);
		return -EINVAL;

	}
	packet = (struct cam_packet *) ((uint8_t *)packet_addr +
		(uint32_t)cmd->offset);

+44 −14
Original line number Diff line number Diff line
@@ -62,9 +62,11 @@ static int cam_cpas_util_vote_bus_client_level(
		return -EINVAL;
	}

	if (level >= bus_client->num_usecases) {
		CAM_ERR(CAM_CPAS, "Invalid vote level=%d, usecases=%d", level,
			bus_client->num_usecases);
	if (level >= CAM_MAX_VOTE) {
		CAM_ERR(CAM_CPAS,
			"Invalid votelevel=%d,usecases=%d,Bus client=[%d][%s]",
			level, bus_client->num_usecases,
			bus_client->client_id, bus_client->name);
		return -EINVAL;
	}

@@ -448,7 +450,7 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate(
	if (soc_private->control_camnoc_axi_clk) {
		struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info;
		uint64_t required_camnoc_bw = 0, intermediate_result = 0;
		int32_t clk_rate = 0;
		int64_t clk_rate = 0;

		for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
			tree_node = soc_private->tree_node[i];
@@ -477,7 +479,7 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate(
		do_div(intermediate_result, soc_private->camnoc_bus_width);
		clk_rate = intermediate_result;

		CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %d",
		CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %lld",
			required_camnoc_bw, clk_rate);

		/*
@@ -490,7 +492,7 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate(
			rc = cam_soc_util_set_src_clk_rate(soc_info, clk_rate);
			if (rc)
				CAM_ERR(CAM_CPAS,
				"Failed in setting camnoc axi clk %llu %d %d",
				"Failed in setting camnoc axi clk %llu %lld %d",
				required_camnoc_bw, clk_rate, rc);
		}
	}
@@ -1180,6 +1182,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
	struct cam_cpas_hw_cmd_start *cmd_hw_start;
	struct cam_cpas_client *cpas_client;
	struct cam_ahb_vote *ahb_vote;
	struct cam_ahb_vote remove_ahb;
	struct cam_axi_vote axi_vote = {0};
	enum cam_vote_level applied_level = CAM_SVS_VOTE;
	int rc, i = 0;
@@ -1241,7 +1244,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
		CAM_ERR(CAM_CPAS, "client=[%d] is not registered",
			client_indx);
		rc = -EPERM;
		goto done;
		goto error;
	}

	if (CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) {
@@ -1249,7 +1252,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
			client_indx, cpas_client->data.identifier,
			cpas_client->data.cell_index);
		rc = -EPERM;
		goto done;
		goto error;
	}

	CAM_DBG(CAM_CPAS,
@@ -1260,7 +1263,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
	rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client,
		ahb_vote, &applied_level);
	if (rc)
		goto done;
		goto error;

	cam_cpas_dump_axi_vote_info(cpas_client, "CPAS Start Vote",
		&axi_vote);
@@ -1281,7 +1284,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
	if (rc) {
		CAM_ERR(CAM_CPAS, "Unable to create or translate paths rc: %d",
			rc);
		goto done;
		goto remove_ahb_vote;
	}

	cam_cpas_dump_axi_vote_info(cpas_client, "CPAS Start Translated Vote",
@@ -1290,7 +1293,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
	rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
		cpas_client, &axi_vote);
	if (rc)
		goto done;
		goto remove_ahb_vote;

	if (cpas_core->streamon_clients == 0) {
		atomic_set(&cpas_core->irq_count, 1);
@@ -1299,7 +1302,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
		if (rc) {
			atomic_set(&cpas_core->irq_count, 0);
			CAM_ERR(CAM_CPAS, "enable_resorce failed, rc=%d", rc);
			goto done;
			goto remove_axi_vote;
		}

		if (cpas_core->internal_ops.power_on) {
@@ -1311,7 +1314,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
				CAM_ERR(CAM_CPAS,
					"failed in power_on settings rc=%d",
					rc);
				goto done;
				goto remove_axi_vote;
			}
		}
		CAM_DBG(CAM_CPAS, "irq_count=%d\n",
@@ -1325,7 +1328,34 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
	CAM_DBG(CAM_CPAS, "client=[%d][%s][%d] streamon_clients=%d",
		client_indx, cpas_client->data.identifier,
		cpas_client->data.cell_index, cpas_core->streamon_clients);
done:

	mutex_unlock(&cpas_core->client_mutex[client_indx]);
	mutex_unlock(&cpas_hw->hw_mutex);
	return rc;

remove_axi_vote:
	memset(&axi_vote, 0x0, sizeof(struct cam_axi_vote));
	rc = cam_cpas_util_create_vote_all_paths(cpas_client, &axi_vote);
	if (rc)
		CAM_ERR(CAM_CPAS, "Unable to create per path votes rc: %d", rc);

	cam_cpas_dump_axi_vote_info(cpas_client, "CPAS Start fail Vote",
		&axi_vote);

	rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
		cpas_client, &axi_vote);
	if (rc)
		CAM_ERR(CAM_CPAS, "Unable to remove axi votes rc: %d", rc);

remove_ahb_vote:
	remove_ahb.type = CAM_VOTE_ABSOLUTE;
	remove_ahb.vote.level = CAM_SUSPEND_VOTE;
	rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client,
		&remove_ahb, NULL);
	if (rc)
		CAM_ERR(CAM_CPAS, "Removing AHB vote failed, rc=%d", rc);

error:
	mutex_unlock(&cpas_core->client_mutex[client_indx]);
	mutex_unlock(&cpas_hw->hw_mutex);
	return rc;
+88 −17
Original line number Diff line number Diff line
@@ -723,6 +723,11 @@ static void __cam_isp_ctx_handle_buf_done_fail_log(
		"Resource Handles that fail to generate buf_done in prev frame");
	for (i = 0; i < req_isp->num_fence_map_out; i++) {
		if (req_isp->fence_map_out[i].sync_id != -1) {
			trace_cam_log_event("Buf_done Congestion",
				__cam_isp_resource_handle_id_to_type(
				req_isp->fence_map_out[i].resource_handle),
				request_id, req_isp->fence_map_out[i].sync_id);

			CAM_WARN(CAM_ISP,
			"Resource_Handle: [%s][0x%x] Sync_ID: [0x%x]",
			__cam_isp_resource_handle_id_to_type(
@@ -766,10 +771,28 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
		}

		if (j == req_isp->num_fence_map_out) {
			if (done_next_req) {
				/*
				 * If not found in current request, it could be
				 * belonging to next request, This can happen if
				 * IRQ delay happens.
				 */
				CAM_WARN(CAM_ISP,
					"BUF_DONE for res 0x%x not found in Req %lld ",
					__cam_isp_resource_handle_id_to_type(
					done->resource_handle[i]),
					req->request_id);

				done_next_req->resource_handle
					[done_next_req->num_handles++] =
					done->resource_handle[i];
			} else {
				CAM_ERR(CAM_ISP,
				"Can not find matching lane handle 0x%x!",
				done->resource_handle[i]);
					"Can not find matching lane handle 0x%x! in Req %lld",
					done->resource_handle[i],
					req->request_id);
				rc = -EINVAL;
			}
			continue;
		}

@@ -779,6 +802,10 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
				req->request_id, i, j,
				__cam_isp_resource_handle_id_to_type(
				done->resource_handle[i]));
			trace_cam_log_event("Duplicate BufDone",
				__cam_isp_resource_handle_id_to_type(
				done->resource_handle[i]),
				req->request_id, ctx->ctx_id);

			if (done_next_req) {
				done_next_req->resource_handle
@@ -979,14 +1006,22 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
}

static int __cam_isp_ctx_apply_req_offline(
	struct cam_context *ctx, uint32_t next_state,
	struct cam_isp_context *ctx_isp)
	void *priv, void *data)
{
	int rc = 0;
	struct cam_context *ctx = NULL;
	struct cam_isp_context *ctx_isp = priv;
	struct cam_ctx_request *req;
	struct cam_isp_ctx_req *req_isp;
	struct cam_hw_config_args cfg;

	if (!ctx_isp) {
		CAM_ERR(CAM_ISP, "Invalid ctx_isp:%pK", ctx);
		rc = -EINVAL;
		goto end;
	}
	ctx = ctx_isp->base;

	if (list_empty(&ctx->pending_req_list)) {
		CAM_DBG(CAM_ISP, "No pending requests to apply");
		rc = -EFAULT;
@@ -999,8 +1034,10 @@ static int __cam_isp_ctx_apply_req_offline(
	if (ctx_isp->active_req_cnt >= 2)
		goto end;

	spin_lock_bh(&ctx->lock);
	req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
		list);
	spin_unlock_bh(&ctx->lock);

	CAM_DBG(CAM_REQ, "Apply request %lld in substate %d ctx %u",
		req->request_id, ctx_isp->substate_activated, ctx->ctx_id);
@@ -1019,13 +1056,21 @@ static int __cam_isp_ctx_apply_req_offline(
	if (rc) {
		CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
	} else {
		spin_lock_bh(&ctx->lock);

		atomic_set(&ctx_isp->rxd_epoch, 0);
		ctx_isp->substate_activated = next_state;

		ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_APPLIED;
		ctx_isp->last_applied_req_id = req->request_id;

		list_del_init(&req->list);
		list_add_tail(&req->list, &ctx->wait_req_list);

		spin_unlock_bh(&ctx->lock);

		CAM_DBG(CAM_ISP, "New substate state %d, applied req %lld",
			next_state, ctx_isp->last_applied_req_id);
			CAM_ISP_CTX_ACTIVATED_APPLIED,
			ctx_isp->last_applied_req_id);

		__cam_isp_ctx_update_state_monitor_array(ctx_isp,
			CAM_ISP_STATE_CHANGE_TRIGGER_APPLIED,
@@ -1035,6 +1080,26 @@ static int __cam_isp_ctx_apply_req_offline(
	return rc;
}

static int __cam_isp_ctx_schedule_apply_req_offline(
	struct cam_isp_context *ctx_isp)
{
	int rc = 0;
	struct crm_workq_task *task;

	task = cam_req_mgr_workq_get_task(ctx_isp->workq);
	if (!task) {
		CAM_ERR(CAM_ISP, "No task for worker");
		return -ENOMEM;
	}

	task->process_cb = __cam_isp_ctx_apply_req_offline;
	rc = cam_req_mgr_workq_enqueue_task(task, ctx_isp, CRM_TASK_PRIORITY_0);
	if (rc)
		CAM_ERR(CAM_ISP, "Failed to schedule task rc:%d", rc);

	return rc;
}

static int __cam_isp_ctx_offline_epoch_in_activated_state(
	struct cam_isp_context *ctx_isp, void *evt_data)
{
@@ -1055,8 +1120,7 @@ static int __cam_isp_ctx_offline_epoch_in_activated_state(
		}
	}

	__cam_isp_ctx_apply_req_offline(ctx, CAM_ISP_CTX_ACTIVATED_APPLIED,
		ctx_isp);
	__cam_isp_ctx_schedule_apply_req_offline(ctx_isp);

	__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
		CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@@ -1422,6 +1486,8 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
		CAM_WARN(CAM_ISP,
			"Notify CRM about Bubble req %lld frame %lld, ctx %u",
			req->request_id, ctx_isp->frame_id, ctx->ctx_id);
		trace_cam_log_event("Bubble", "Rcvd epoch in applied state",
			req->request_id, ctx->ctx_id);
		ctx->ctx_crm_intf->notify_err(&notify);
		atomic_set(&ctx_isp->process_bubble, 1);
	} else {
@@ -3818,10 +3884,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
		req->request_id, ctx->ctx_id);

	if (ctx_isp->offline_context && atomic_read(&ctx_isp->rxd_epoch)) {
		spin_lock_bh(&ctx->lock);
		__cam_isp_ctx_apply_req_offline(ctx,
			CAM_ISP_CTX_ACTIVATED_APPLIED, ctx_isp);
		spin_unlock_bh(&ctx->lock);
		__cam_isp_ctx_schedule_apply_req_offline(ctx_isp);
	}

	return rc;
@@ -4267,6 +4330,13 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
			cam_isp_ctx_offline_state_machine_irq;
		ctx_isp->substate_machine = NULL;
		ctx_isp->offline_context = true;

		rc = cam_req_mgr_workq_create("offline_ife", 20,
			&ctx_isp->workq, CRM_WORKQ_USAGE_IRQ, 0);
		if (rc)
			CAM_ERR(CAM_ISP,
				"Failed to create workq for offline IFE rc:%d",
				rc);
	} else {
		CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
		ctx_isp->substate_machine_irq =
@@ -5180,6 +5250,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
		atomic64_set(&ctx->event_record_head[i], -1);

	cam_isp_context_debug_register();

err:
	return rc;
}
Loading