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

Commit c83f67df authored by Camera Software Integration's avatar Camera Software Integration Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: reqmgr: Add notify frame skip interface" into camera-kernel.lnx.4.0

parents 9d1494c4 c782e8c3
Loading
Loading
Loading
Loading
+7 −6
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>
@@ -182,7 +182,7 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx,
	return rc;
}

int cam_context_handle_crm_apply_default_req(
int cam_context_handle_crm_notify_frame_skip(
	struct cam_context *ctx,
	struct cam_req_mgr_apply_request *apply)
{
@@ -199,11 +199,12 @@ int cam_context_handle_crm_apply_default_req(
	}

	mutex_lock(&ctx->ctx_mutex);
	if (ctx->state_machine[ctx->state].crm_ops.apply_default)
		rc = ctx->state_machine[ctx->state].crm_ops.apply_default(ctx,
			apply);
	if (ctx->state_machine[ctx->state].crm_ops.notify_frame_skip)
		rc = ctx->state_machine[ctx->state].crm_ops.notify_frame_skip(
			ctx, apply);
	else
		CAM_DBG(CAM_CORE, "No crm apply_default in dev %d, state %d",
		CAM_DBG(CAM_CORE,
			"No crm notify_frame_skip in dev %d, state %d",
			ctx->dev_hdl, ctx->state);
	mutex_unlock(&ctx->ctx_mutex);

+7 −7
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_CONTEXT_H_
@@ -121,7 +121,7 @@ struct cam_ctx_ioctl_ops {
 * @link:                  Link the context
 * @unlink:                Unlink the context
 * @apply_req:             Apply setting for the context
 * @apply_default:         Apply default settings for the context
 * @notify_frame_skip:     Notify device that a frame is skipped
 * @flush_req:             Flush request to remove request ids
 * @process_evt:           Handle event notification from CRM.(optional)
 * @dump_req:              Dump information for the issue request
@@ -136,7 +136,7 @@ struct cam_ctx_crm_ops {
			struct cam_req_mgr_core_dev_link_setup *unlink);
	int (*apply_req)(struct cam_context *ctx,
			struct cam_req_mgr_apply_request *apply);
	int (*apply_default)(struct cam_context *ctx,
	int (*notify_frame_skip)(struct cam_context *ctx,
			struct cam_req_mgr_apply_request *apply);
	int (*flush_req)(struct cam_context *ctx,
			struct cam_req_mgr_flush_request *flush);
@@ -306,15 +306,15 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx,
		struct cam_req_mgr_apply_request *apply);

/**
 * cam_context_handle_crm_apply_default_req()
 * cam_context_handle_crm_notify_frame_skip()
 *
 * @brief:        Handle apply default request command
 * @brief:        Handle notify frame skip command
 *
 * @ctx:          Object pointer for cam_context
 * @apply:        Apply default request command payload
 * @apply:        Notify frame skip command payload
 *
 */
int cam_context_handle_crm_apply_default_req(
int cam_context_handle_crm_notify_frame_skip(
	struct cam_context *ctx, struct cam_req_mgr_apply_request *apply);

/**
+5 −4
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>
@@ -570,7 +570,7 @@ static int __cam_node_crm_apply_req(struct cam_req_mgr_apply_request *apply)
	return cam_context_handle_crm_apply_req(ctx, apply);
}

static int __cam_node_crm_apply_default_req(
static int __cam_node_crm_notify_frame_skip(
	struct cam_req_mgr_apply_request *apply)
{
	struct cam_context *ctx = NULL;
@@ -587,7 +587,7 @@ static int __cam_node_crm_apply_default_req(

	trace_cam_apply_req("Node", apply->request_id);

	return cam_context_handle_crm_apply_default_req(ctx, apply);
	return cam_context_handle_crm_notify_frame_skip(ctx, apply);
}

static int __cam_node_crm_flush_req(struct cam_req_mgr_flush_request *flush)
@@ -703,7 +703,8 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
	node->crm_node_intf.flush_req = __cam_node_crm_flush_req;
	node->crm_node_intf.process_evt = __cam_node_crm_process_evt;
	node->crm_node_intf.dump_req = __cam_node_crm_dump_req;
	node->crm_node_intf.apply_default = __cam_node_crm_apply_default_req;
	node->crm_node_intf.notify_frame_skip =
		__cam_node_crm_notify_frame_skip;

	mutex_init(&node->list_mutex);
	INIT_LIST_HEAD(&node->free_ctx_list);
+5 −6
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ static struct cam_ctx_ops
		.ioctl_ops = {},
		.crm_ops = {
			.apply_req = __cam_custom_ctx_apply_req_in_activated,
			.apply_default =
			.notify_frame_skip =
				__cam_custom_ctx_apply_default_settings,
		},
		.irq_ops = NULL,
@@ -229,7 +229,7 @@ static struct cam_ctx_ops
		.ioctl_ops = {},
		.crm_ops = {
			.apply_req = __cam_custom_ctx_apply_req_in_activated,
			.apply_default =
			.notify_frame_skip =
				__cam_custom_ctx_apply_default_settings,
		},
		.irq_ops = NULL,
@@ -414,7 +414,6 @@ static int __cam_custom_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
	dev_info->dev_id = CAM_REQ_MGR_DEVICE_CUSTOM_HW;
	dev_info->p_delay = 1;
	dev_info->trigger = CAM_TRIGGER_POINT_SOF;
	dev_info->enable_apply_default = true;

	return 0;
}
@@ -1452,8 +1451,8 @@ static int __cam_custom_ctx_apply_default_req(

	ctx_ops = &custom_ctx->substate_machine[
		custom_ctx->substate_activated];
	if (ctx_ops->crm_ops.apply_default) {
		rc = ctx_ops->crm_ops.apply_default(ctx, apply);
	if (ctx_ops->crm_ops.notify_frame_skip) {
		rc = ctx_ops->crm_ops.notify_frame_skip(ctx, apply);
	} else {
		CAM_WARN_RATE_LIMIT(CAM_CUSTOM,
			"No handle function in activated substate %d",
@@ -1547,7 +1546,7 @@ static struct cam_ctx_ops
		.crm_ops = {
			.unlink = __cam_custom_ctx_unlink_in_activated,
			.apply_req = __cam_custom_ctx_apply_req,
			.apply_default =
			.notify_frame_skip =
				__cam_custom_ctx_apply_default_req,
			.flush_req = __cam_custom_ctx_flush_req_in_top_state,
			.process_evt = __cam_custom_ctx_process_evt,
+103 −70
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ static struct cam_req_mgr_core_link g_links[MAXIMUM_LINKS_PER_SESSION];

void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
{
	uint32_t pd = 0;

	link->link_hdl = 0;
	link->num_devs = 0;
	link->max_delay = CAM_PIPELINE_DELAY_0;
@@ -49,9 +51,13 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
	link->initial_skip = true;
	link->sof_timestamp = 0;
	link->prev_sof_timestamp = 0;
	link->enable_apply_default = false;
	link->skip_init_frame = false;
	atomic_set(&link->eof_event_cnt, 0);

	for (pd = 0; pd < CAM_PIPELINE_DELAY_MAX; pd++) {
		link->req.apply_data[pd].req_id = -1;
		link->req.prev_apply_data[pd].req_id = -1;
	}
}

void cam_req_mgr_handle_core_shutdown(void)
@@ -212,32 +218,77 @@ static void __cam_req_mgr_find_dev_name(
}

/**
 * __cam_req_mgr_apply_default()
 * __cam_req_mgr_notify_frame_skip()
 *
 * @brief : Apply default settings to all devices
 * @brief : Notify all devices of frame skipping
 * @link  : link on which we are applying these settings
 *
 */
static void __cam_req_mgr_apply_default(
	struct cam_req_mgr_core_link *link)
static int __cam_req_mgr_notify_frame_skip(
	struct cam_req_mgr_core_link *link,
	uint32_t trigger)
{
	int                                  i;
	struct cam_req_mgr_apply_request     apply_req;
	int                                  rc = 0, i, pd, idx;
	struct cam_req_mgr_apply_request     frame_skip;
	struct cam_req_mgr_apply            *apply_data = NULL;
	struct cam_req_mgr_connected_device *dev = NULL;
	struct cam_req_mgr_tbl_slot         *slot = NULL;

	if (!link->enable_apply_default)
		return;
	apply_data = link->req.prev_apply_data;

	for (i = 0; i < link->num_devs; i++) {
		dev = &link->l_dev[i];
		apply_req.request_id = 0;
		apply_req.dev_hdl = dev->dev_hdl;
		apply_req.link_hdl = link->link_hdl;
		apply_req.trigger_point = 0;
		apply_req.report_if_bubble = 0;
		if (dev->ops && dev->ops->apply_default)
			dev->ops->apply_default(&apply_req);
		if (!dev)
			continue;

		pd = dev->dev_info.p_delay;
		if (pd >= CAM_PIPELINE_DELAY_MAX) {
			CAM_WARN(CAM_CRM, "pd %d greater than max",
				pd);
			continue;
		}

		idx = apply_data[pd].idx;
		slot = &dev->pd_tbl->slot[idx];

		if ((slot->ops.dev_hdl == dev->dev_hdl) &&
			(slot->ops.is_applied)) {
			slot->ops.is_applied = false;
			continue;
		}

		/*
		 * If apply_at_eof is enabled do not apply at SOF
		 * e.x. Flash device
		 */
		if ((trigger == CAM_TRIGGER_POINT_SOF) &&
			(dev->dev_hdl == slot->ops.dev_hdl) &&
			(slot->ops.apply_at_eof))
			continue;

		/*
		 * If apply_at_eof is not enabled ignore EOF
		 */
		if ((trigger == CAM_TRIGGER_POINT_EOF) &&
			(dev->dev_hdl == slot->ops.dev_hdl) &&
			(!slot->ops.apply_at_eof))
			continue;

		frame_skip.dev_hdl = dev->dev_hdl;
		frame_skip.link_hdl = link->link_hdl;
		frame_skip.request_id =
			apply_data[pd].req_id;
		frame_skip.trigger_point = trigger;
		frame_skip.report_if_bubble = 0;

		CAM_DBG(CAM_REQ,
			"Notify_frame_skip: pd %d req_id %lld",
			link->link_hdl, pd, apply_data[pd].req_id);
		if ((dev->ops) && (dev->ops->notify_frame_skip))
			dev->ops->notify_frame_skip(&frame_skip);
	}

	return rc;
}

/**
@@ -716,6 +767,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_apply_request     apply_req;
	struct cam_req_mgr_link_evt_data     evt_data;
	struct cam_req_mgr_tbl_slot          *slot = NULL;
	struct cam_req_mgr_apply             *apply_data = NULL;

	apply_req.link_hdl = link->link_hdl;
	apply_req.report_if_bubble = 0;
@@ -725,6 +777,8 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
			apply_req.re_apply = true;
	}

	apply_data = link->req.apply_data;

	/*
	 * This For loop is to address the special operation requested
	 * by device
@@ -740,7 +794,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
			continue;
		}

		idx = link->req.apply_data[pd].idx;
		idx = apply_data[pd].idx;
		slot = &dev->pd_tbl->slot[idx];

		if (slot->ops.dev_hdl < 0) {
@@ -772,20 +826,21 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
		if ((trigger == CAM_TRIGGER_POINT_EOF) &&
			(!slot->ops.apply_at_eof)) {
			CAM_DBG(CAM_CRM, "NO EOF DATA FOR REQ: %llu",
				link->req.apply_data[pd].req_id);
				apply_data[pd].req_id);
			break;
		}

		apply_req.dev_hdl = dev->dev_hdl;
		apply_req.request_id =
			link->req.apply_data[pd].req_id;
			apply_data[pd].req_id;
		apply_req.trigger_point = trigger;
		if ((dev->ops) && (dev->ops->apply_req) &&
			(!slot->ops.is_applied)) {
			rc = dev->ops->apply_req(&apply_req);
			if (rc) {
				*failed_dev = dev;
				__cam_req_mgr_apply_default(link);
				__cam_req_mgr_notify_frame_skip(link,
					trigger);
				return rc;
			}
		}
@@ -801,7 +856,8 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
			CAM_DBG(CAM_REQ,
				"SEND: link_hdl: %x pd: %d req_id %lld",
				link->link_hdl, pd, apply_req.request_id);
			__cam_req_mgr_apply_default(link);
			__cam_req_mgr_notify_frame_skip(link,
				trigger);
			return -EAGAIN;
		} else if ((trigger == CAM_TRIGGER_POINT_EOF) &&
			(slot->ops.apply_at_eof)) {
@@ -810,7 +866,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
				atomic_dec(&link->eof_event_cnt);
			CAM_DBG(CAM_REQ,
				"Req_id: %llu eof_event_cnt : %d",
				link->req.apply_data[pd].req_id,
				apply_data[pd].req_id,
				link->eof_event_cnt);
			return 0;
		}
@@ -830,27 +886,27 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
			if (!(dev->dev_info.trigger & trigger))
				continue;

			if (link->req.apply_data[pd].skip_idx ||
				(link->req.apply_data[pd].req_id < 0)) {
			if (apply_data[pd].skip_idx ||
				(apply_data[pd].req_id < 0)) {
				CAM_DBG(CAM_CRM,
					"dev %s skip %d req_id %lld",
					dev->dev_info.name,
					link->req.apply_data[pd].skip_idx,
					link->req.apply_data[pd].req_id);
					apply_data[pd].skip_idx,
					apply_data[pd].req_id);
				apply_req.dev_hdl = dev->dev_hdl;
				apply_req.request_id = 0;
				apply_req.request_id =
					link->req.prev_apply_data[pd].req_id;
				apply_req.trigger_point = 0;
				apply_req.report_if_bubble = 0;
				if ((link->enable_apply_default) &&
					(dev->ops) && (dev->ops->apply_default))
					dev->ops->apply_default(&apply_req);
				if ((dev->ops) && (dev->ops->notify_frame_skip))
					dev->ops->notify_frame_skip(&apply_req);
				continue;
			}

			apply_req.dev_hdl = dev->dev_hdl;
			apply_req.request_id =
				link->req.apply_data[pd].req_id;
			idx = link->req.apply_data[pd].idx;
				apply_data[pd].req_id;
			idx = apply_data[pd].idx;
			slot = &dev->pd_tbl->slot[idx];
			apply_req.report_if_bubble =
				in_q->slot[idx].recover;
@@ -880,7 +936,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,

			apply_req.trigger_point = trigger;
			CAM_DBG(CAM_REQ,
				"SEND: link_hdl: %x pd %d req_id %lld",
				"SEND: %d link_hdl: %x pd %d req_id %lld",
				link->link_hdl, pd, apply_req.request_id);
			if (dev->ops && dev->ops->apply_req) {
				rc = dev->ops->apply_req(&apply_req);
@@ -906,8 +962,13 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
			if (dev->ops && dev->ops->process_evt)
				dev->ops->process_evt(&evt_data);
		}
		__cam_req_mgr_apply_default(link);
		__cam_req_mgr_notify_frame_skip(link, trigger);
	} else {
		memcpy(link->req.prev_apply_data, link->req.apply_data,
			CAM_PIPELINE_DELAY_MAX *
			sizeof(struct cam_req_mgr_apply));
	}

	return rc;
}

@@ -1598,7 +1659,7 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
				rc = -EPERM;
			}
			spin_unlock_bh(&link->link_state_spin_lock);
			__cam_req_mgr_apply_default(link);
			__cam_req_mgr_notify_frame_skip(link, trigger);
			goto error;
		}
	}
@@ -2197,38 +2258,6 @@ static void __cam_req_mgr_unreserve_link(

/* Workqueue context processing section */

/**
 * cam_req_mgr_process_send_req()
 *
 * @brief: This runs in workque thread context. Call core funcs to send
 *         apply request id to drivers.
 * @priv : link information.
 * @data : contains information about frame_id, link etc.
 *
 * @return: 0 on success.
 */
int cam_req_mgr_process_send_req(void *priv, void *data)
{
	int                                 rc = 0;
	struct cam_req_mgr_core_link        *link = NULL;
	struct cam_req_mgr_send_request     *send_req = NULL;
	struct cam_req_mgr_req_queue        *in_q = NULL;
	struct cam_req_mgr_connected_device *dev;

	if (!data || !priv) {
		CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
		rc = -EINVAL;
		goto end;
	}
	link = (struct cam_req_mgr_core_link *)priv;
	send_req = (struct cam_req_mgr_send_request *)data;
	in_q = send_req->in_q;

	rc = __cam_req_mgr_send_req(link, in_q, CAM_TRIGGER_POINT_SOF, &dev);
end:
	return rc;
}

/**
 * cam_req_mgr_process_flush_req()
 *
@@ -2242,6 +2271,7 @@ int cam_req_mgr_process_send_req(void *priv, void *data)
int cam_req_mgr_process_flush_req(void *priv, void *data)
{
	int                                  rc = 0, i = 0, idx = -1;
	uint32_t                             pd = 0;
	struct cam_req_mgr_flush_info       *flush_info = NULL;
	struct cam_req_mgr_core_link        *link = NULL;
	struct cam_req_mgr_req_queue        *in_q = NULL;
@@ -2306,6 +2336,12 @@ int cam_req_mgr_process_flush_req(void *priv, void *data)
		if (device->ops && device->ops->flush_req)
			rc = device->ops->flush_req(&flush_req);
	}

	for (pd = 0; pd < CAM_PIPELINE_DELAY_MAX; pd++) {
		link->req.apply_data[pd].req_id = -1;
		link->req.prev_apply_data[pd].req_id = -1;
	}

	complete(&link->workq_comp);
	mutex_unlock(&link->req.lock);

@@ -3297,9 +3333,6 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
			if (dev->dev_info.p_delay > max_delay)
				max_delay = dev->dev_info.p_delay;

			if (dev->dev_info.enable_apply_default)
				link->enable_apply_default = true;

			subscribe_event |= (uint32_t)dev->dev_info.trigger;
		}

Loading