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

Commit 89fa9705 authored by Junzhe Zou's avatar Junzhe Zou
Browse files

msm: camera: isp: support composite fence id



To reduce the fence cb traffic, UMD can configure several buffer
as a group with the same fence id. To support it, IFE kernel
only signal the fence once for each fence id.

Change-Id: Ia7c41df6b997707678cf7e5be6860b776c7ad0eb
Signed-off-by: default avatarJunzhe Zou <jnzhezou@codeaurora.org>
parent 2e387d22
Loading
Loading
Loading
Loading
+22 −6
Original line number Original line Diff line number Diff line
@@ -275,7 +275,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
	uint64_t packet_addr;
	uint64_t packet_addr;
	struct cam_packet *packet;
	struct cam_packet *packet;
	size_t len = 0;
	size_t len = 0;
	int32_t i = 0;
	int32_t i = 0, j = 0;


	if (!ctx || !cmd) {
	if (!ctx || !cmd) {
		CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
		CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
@@ -355,6 +355,15 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
	req->status = 1;
	req->status = 1;
	req->req_priv = cfg.priv;
	req->req_priv = cfg.priv;


	for (i = 0; i < req->num_out_map_entries; i++) {
		rc = cam_sync_get_obj_ref(req->out_map_entries[i].sync_id);
		if (rc) {
			CAM_ERR(CAM_CTXT, "Can't get ref for sync %d",
				req->out_map_entries[i].sync_id);
			goto put_ref;
		}
	}

	if (req->num_in_map_entries > 0) {
	if (req->num_in_map_entries > 0) {
		spin_lock(&ctx->lock);
		spin_lock(&ctx->lock);
		list_add_tail(&req->list, &ctx->pending_req_list);
		list_add_tail(&req->list, &ctx->pending_req_list);
@@ -365,17 +374,17 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
				"[%s][%d] : Moving req[%llu] from free_list to pending_list",
				"[%s][%d] : Moving req[%llu] from free_list to pending_list",
				ctx->dev_name, ctx->ctx_id, req->request_id);
				ctx->dev_name, ctx->ctx_id, req->request_id);


		for (i = 0; i < req->num_in_map_entries; i++) {
		for (j = 0; j < req->num_in_map_entries; j++) {
			cam_context_getref(ctx);
			cam_context_getref(ctx);
			rc = cam_sync_register_callback(
			rc = cam_sync_register_callback(
					cam_context_sync_callback,
					cam_context_sync_callback,
					(void *)req,
					(void *)req,
					req->in_map_entries[i].sync_id);
					req->in_map_entries[j].sync_id);
			if (rc) {
			if (rc) {
				CAM_ERR(CAM_CTXT,
				CAM_ERR(CAM_CTXT,
					"[%s][%d] Failed register fence cb: %d ret = %d",
					"[%s][%d] Failed register fence cb: %d ret = %d",
					ctx->dev_name, ctx->ctx_id,
					ctx->dev_name, ctx->ctx_id,
					req->in_map_entries[i].sync_id, rc);
					req->in_map_entries[j].sync_id, rc);
				spin_lock(&ctx->lock);
				spin_lock(&ctx->lock);
				list_del_init(&req->list);
				list_del_init(&req->list);
				spin_unlock(&ctx->lock);
				spin_unlock(&ctx->lock);
@@ -388,16 +397,23 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,


				cam_context_putref(ctx);
				cam_context_putref(ctx);


				goto free_req;
				goto put_ref;
			}
			}
			CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d",
			CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d",
				req->in_map_entries[i].sync_id, rc);
				req->in_map_entries[j].sync_id, rc);
		}
		}
		goto end;
		goto end;
	}
	}


	return rc;
	return rc;


put_ref:
	for (--i; i >= 0; i--) {
		rc = cam_sync_put_obj_ref(req->out_map_entries[i].sync_id);
		if (rc)
			CAM_ERR(CAM_CTXT, "Failed to put ref of fence %d",
				req->out_map_entries[i].sync_id);
	}
free_req:
free_req:
	spin_lock(&ctx->lock);
	spin_lock(&ctx->lock);
	list_add_tail(&req->list, &ctx->free_req_list);
	list_add_tail(&req->list, &ctx->free_req_list);
+6 −0
Original line number Original line Diff line number Diff line
@@ -50,6 +50,7 @@
#include "cam_soc_util.h"
#include "cam_soc_util.h"
#include "cam_trace.h"
#include "cam_trace.h"
#include "cam_cpas_api.h"
#include "cam_cpas_api.h"
#include "cam_common_util.h"


#define ICP_WORKQ_TASK_CMD_TYPE 1
#define ICP_WORKQ_TASK_CMD_TYPE 1
#define ICP_WORKQ_TASK_MSG_TYPE 2
#define ICP_WORKQ_TASK_MSG_TYPE 2
@@ -3394,6 +3395,11 @@ static int cam_icp_mgr_process_io_cfg(struct cam_icp_hw_mgr *hw_mgr,
			io_cfg_ptr[i].resource_type);
			io_cfg_ptr[i].resource_type);
	}
	}


	if (prepare_args->num_in_map_entries > 1)
		prepare_args->num_in_map_entries =
			cam_common_util_remove_duplicate_arr(
			sync_in_obj, prepare_args->num_in_map_entries);

	if (prepare_args->num_in_map_entries > 1) {
	if (prepare_args->num_in_map_entries > 1) {
		rc = cam_sync_merge(&sync_in_obj[0],
		rc = cam_sync_merge(&sync_in_obj[0],
			prepare_args->num_in_map_entries, &merged_sync_in_obj);
			prepare_args->num_in_map_entries, &merged_sync_in_obj);
+18 −2
Original line number Original line Diff line number Diff line
@@ -1996,7 +1996,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
static int __cam_isp_ctx_config_dev_in_top_state(
static int __cam_isp_ctx_config_dev_in_top_state(
	struct cam_context *ctx, struct cam_config_dev_cmd *cmd)
	struct cam_context *ctx, struct cam_config_dev_cmd *cmd)
{
{
	int rc = 0;
	int rc = 0, i;
	struct cam_ctx_request           *req = NULL;
	struct cam_ctx_request           *req = NULL;
	struct cam_isp_ctx_req           *req_isp;
	struct cam_isp_ctx_req           *req_isp;
	uint64_t                          packet_addr;
	uint64_t                          packet_addr;
@@ -2072,6 +2072,15 @@ static int __cam_isp_ctx_config_dev_in_top_state(
	req_isp->num_fence_map_in = cfg.num_in_map_entries;
	req_isp->num_fence_map_in = cfg.num_in_map_entries;
	req_isp->num_acked = 0;
	req_isp->num_acked = 0;


	for (i = 0; i < req_isp->num_fence_map_out; i++) {
		rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id);
		if (rc) {
			CAM_ERR(CAM_ISP, "Can't get ref for fence %d",
				req_isp->fence_map_out[i].sync_id);
			goto put_ref;
		}
	}

	CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
	CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
		req_isp->num_cfg, req_isp->num_fence_map_out,
		req_isp->num_cfg, req_isp->num_fence_map_out,
		req_isp->num_fence_map_in);
		req_isp->num_fence_map_in);
@@ -2113,7 +2122,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
		}
		}
	}
	}
	if (rc)
	if (rc)
		goto free_req;
		goto put_ref;


	CAM_DBG(CAM_REQ,
	CAM_DBG(CAM_REQ,
		"Preprocessing Config req_id %lld successful on ctx %u",
		"Preprocessing Config req_id %lld successful on ctx %u",
@@ -2121,6 +2130,13 @@ static int __cam_isp_ctx_config_dev_in_top_state(


	return rc;
	return rc;


put_ref:
	for (--i; i >= 0; i--) {
		rc = cam_sync_put_obj_ref(req_isp->fence_map_out[i].sync_id);
		if (rc)
			CAM_ERR(CAM_CTXT, "Failed to put ref of fence %d",
				req_isp->fence_map_out[i].sync_id);
	}
free_req:
free_req:
	spin_lock_bh(&ctx->lock);
	spin_lock_bh(&ctx->lock);
	list_add_tail(&req->list, &ctx->free_req_list);
	list_add_tail(&req->list, &ctx->free_req_list);
+54 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/debugfs.h>
#include <linux/debugfs.h>
#include "cam_sync_util.h"
#include "cam_sync_util.h"
#include "cam_debug_util.h"
#include "cam_debug_util.h"
#include "cam_common_util.h"


struct sync_device *sync_dev;
struct sync_device *sync_dev;


@@ -221,6 +222,11 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status)
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (!atomic_dec_and_test(&row->ref_cnt)) {
		spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
		return 0;
	}

	row->state = status;
	row->state = status;
	cam_sync_util_dispatch_signaled_cb(sync_obj, status);
	cam_sync_util_dispatch_signaled_cb(sync_obj, status);


@@ -284,6 +290,12 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (cam_common_util_remove_duplicate_arr(sync_obj, num_objs)
		!= num_objs) {
		CAM_ERR(CAM_SYNC, "The obj list has duplicate fence");
		return -EINVAL;
	}

	do {
	do {
		idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
		idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
		if (idx >= CAM_SYNC_MAX_OBJS)
		if (idx >= CAM_SYNC_MAX_OBJS)
@@ -309,6 +321,46 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
	return 0;
	return 0;
}
}


int cam_sync_get_obj_ref(int32_t sync_obj)
{
	struct sync_table_row *row = NULL;

	if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
		return -EINVAL;

	row = sync_dev->sync_table + sync_obj;

	spin_lock(&sync_dev->row_spinlocks[sync_obj]);

	if (row->state != CAM_SYNC_STATE_ACTIVE) {
		spin_unlock(&sync_dev->row_spinlocks[sync_obj]);
		CAM_ERR(CAM_SYNC,
			"Error: accessing an uninitialized sync obj = %d",
			sync_obj);
		return -EINVAL;
	}

	atomic_inc(&row->ref_cnt);
	spin_unlock(&sync_dev->row_spinlocks[sync_obj]);
	CAM_DBG(CAM_SYNC, "get ref for obj %d", sync_obj);

	return 0;
}

int cam_sync_put_obj_ref(int32_t sync_obj)
{
	struct sync_table_row *row = NULL;

	if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
		return -EINVAL;

	row = sync_dev->sync_table + sync_obj;
	atomic_dec(&row->ref_cnt);
	CAM_DBG(CAM_SYNC, "put ref for obj %d", sync_obj);

	return 0;
}

int cam_sync_destroy(int32_t sync_obj)
int cam_sync_destroy(int32_t sync_obj)
{
{
	CAM_DBG(CAM_SYNC, "sync_obj: %i", sync_obj);
	CAM_DBG(CAM_SYNC, "sync_obj: %i", sync_obj);
@@ -405,6 +457,8 @@ static int cam_sync_handle_signal(struct cam_private_ioctl_arg *k_ioctl)
		k_ioctl->size))
		k_ioctl->size))
		return -EFAULT;
		return -EFAULT;


	/* need to get ref for UMD signaled fences */
	cam_sync_get_obj_ref(sync_signal.sync_obj);
	return cam_sync_signal(sync_signal.sync_obj,
	return cam_sync_signal(sync_signal.sync_obj,
		sync_signal.sync_state);
		sync_signal.sync_state);
}
}
+23 −0
Original line number Original line Diff line number Diff line
@@ -100,6 +100,29 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status);
 */
 */
int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj);
int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj);


/**
 * @brief: get ref count of sync obj
 *
 * This function will increment ref count for the sync object, and the ref
 * count will be decremented when this sync object is signaled.
 *
 * @param sync_obj: sync object
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_sync_get_obj_ref(int32_t sync_obj);

/**
 * @brief: put ref count of sync obj
 *
 * This function will decrement ref count for the sync object.
 *
 * @param sync_obj: sync object
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_sync_put_obj_ref(int32_t sync_obj);

/**
/**
 * @brief: Destroys a sync object
 * @brief: Destroys a sync object
 *
 *
Loading