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

Commit 34922264 authored by Jeyaprakash Soundrapandian's avatar Jeyaprakash Soundrapandian Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: isp: Improve the csid resource allocation" into dev/msm-4.9-camx

parents a6036775 5968920d
Loading
Loading
Loading
Loading
+109 −102
Original line number Diff line number Diff line
@@ -860,10 +860,95 @@ static int cam_ife_hw_mgr_acquire_res_ife_src(
	return rc;
}

static int cam_ife_hw_mgr_acquire_res_ife_csid_ipp(
static int cam_ife_mgr_acquire_cid_res(
	struct cam_ife_hw_mgr_ctx          *ife_ctx,
	struct cam_isp_in_port_info        *in_port,
	uint32_t                            cid_res_id)
	uint32_t                           *cid_res_id,
	enum cam_ife_pix_path_res_id        csid_path)
{
	int rc = -1;
	int i, j;
	struct cam_ife_hw_mgr               *ife_hw_mgr;
	struct cam_ife_hw_mgr_res           *cid_res;
	struct cam_hw_intf                  *hw_intf;
	struct cam_csid_hw_reserve_resource_args  csid_acquire;

	ife_hw_mgr = ife_ctx->hw_mgr;

	rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &cid_res);
	if (rc) {
		CAM_ERR(CAM_ISP, "No more free hw mgr resource");
		goto err;
	}
	cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_cid, &cid_res);

	csid_acquire.res_type = CAM_ISP_RESOURCE_CID;
	csid_acquire.in_port = in_port;
	csid_acquire.res_id =  csid_path;

	for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) {
		if (!ife_hw_mgr->csid_devices[i])
			continue;

		hw_intf = ife_hw_mgr->csid_devices[i];
		rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &csid_acquire,
			sizeof(csid_acquire));
		if (rc)
			continue;
		else
			break;
	}

	if (i == CAM_IFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) {
		CAM_ERR(CAM_ISP, "Can not acquire ife csid rdi resource");
		goto err;
	}

	cid_res->res_type = CAM_IFE_HW_MGR_RES_CID;
	cid_res->res_id = csid_acquire.node_res->res_id;
	cid_res->is_dual_vfe = in_port->usage_type;
	cid_res->hw_res[0] = csid_acquire.node_res;
	cid_res->hw_res[1] = NULL;
	/* CID(DT_ID) value of acquire device, require for path */
	*cid_res_id = csid_acquire.node_res->res_id;

	if (cid_res->is_dual_vfe) {
		csid_acquire.node_res = NULL;
		csid_acquire.res_type = CAM_ISP_RESOURCE_CID;
		csid_acquire.in_port = in_port;
		for (j = i + 1; j < CAM_IFE_CSID_HW_NUM_MAX; j++) {
			if (!ife_hw_mgr->csid_devices[j])
				continue;

			hw_intf = ife_hw_mgr->csid_devices[j];
			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
				&csid_acquire, sizeof(csid_acquire));
			if (rc)
				continue;
			else
				break;
		}

		if (j == CAM_IFE_CSID_HW_NUM_MAX) {
			CAM_ERR(CAM_ISP,
				"Can not acquire ife csid rdi resource");
			goto err;
		}
		cid_res->hw_res[1] = csid_acquire.node_res;
	}
	cid_res->parent = &ife_ctx->res_list_ife_in;
	ife_ctx->res_list_ife_in.child[
		ife_ctx->res_list_ife_in.num_children++] = cid_res;

	return 0;
err:
	return rc;

}

static int cam_ife_hw_mgr_acquire_res_ife_csid_ipp(
	struct cam_ife_hw_mgr_ctx          *ife_ctx,
	struct cam_isp_in_port_info        *in_port)
{
	int rc = -1;
	int i;
@@ -872,8 +957,17 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_ipp(
	struct cam_ife_hw_mgr_res           *csid_res;
	struct cam_ife_hw_mgr_res           *cid_res;
	struct cam_hw_intf                  *hw_intf;
	uint32_t                             cid_res_id;
	struct cam_csid_hw_reserve_resource_args  csid_acquire;

	/* get cid resource */
	rc = cam_ife_mgr_acquire_cid_res(ife_ctx, in_port, &cid_res_id,
		CAM_IFE_PIX_PATH_RES_IPP);
	if (rc) {
		CAM_ERR(CAM_ISP, "Acquire IFE CID resource Failed");
		goto err;
	}

	ife_hw_mgr = ife_ctx->hw_mgr;

	rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &csid_res);
@@ -985,8 +1079,7 @@ static enum cam_ife_pix_path_res_id

static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi(
	struct cam_ife_hw_mgr_ctx     *ife_ctx,
	struct cam_isp_in_port_info   *in_port,
	uint32_t                       cid_res_id)
	struct cam_isp_in_port_info   *in_port)
{
	int rc = -1;
	int i, j;
@@ -996,6 +1089,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi(
	struct cam_ife_hw_mgr_res           *cid_res;
	struct cam_hw_intf                  *hw_intf;
	struct cam_isp_out_port_info        *out_port;
	uint32_t                            cid_res_id;
	struct cam_csid_hw_reserve_resource_args  csid_acquire;

	ife_hw_mgr = ife_ctx->hw_mgr;
@@ -1005,6 +1099,15 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi(
		if (!cam_ife_hw_mgr_is_rdi_res(out_port->res_type))
			continue;

		/* get cid resource */
		rc = cam_ife_mgr_acquire_cid_res(ife_ctx, in_port, &cid_res_id,
			cam_ife_hw_mgr_get_ife_csid_rdi_res_type(
			out_port->res_type));
		if (rc) {
			CAM_ERR(CAM_ISP, "Acquire IFE CID resource Failed");
			goto err;
		}

		rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list,
			&csid_res);
		if (rc) {
@@ -1135,91 +1238,6 @@ static int cam_ife_hw_mgr_preprocess_out_port(
	return 0;
}

static int cam_ife_mgr_acquire_cid_res(
	struct cam_ife_hw_mgr_ctx          *ife_ctx,
	struct cam_isp_in_port_info        *in_port,
	uint32_t                           *cid_res_id,
	int                                 pixel_count)
{
	int rc = -1;
	int i, j;
	struct cam_ife_hw_mgr               *ife_hw_mgr;
	struct cam_ife_hw_mgr_res           *cid_res;
	struct cam_hw_intf                  *hw_intf;
	struct cam_csid_hw_reserve_resource_args  csid_acquire;

	ife_hw_mgr = ife_ctx->hw_mgr;

	rc = cam_ife_hw_mgr_get_res(&ife_ctx->free_res_list, &cid_res);
	if (rc) {
		CAM_ERR(CAM_ISP, "No more free hw mgr resource");
		goto err;
	}
	cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_cid, &cid_res);

	csid_acquire.res_type = CAM_ISP_RESOURCE_CID;
	csid_acquire.in_port = in_port;
	csid_acquire.pixel_count = pixel_count;

	for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) {
		if (!ife_hw_mgr->csid_devices[i])
			continue;

		hw_intf = ife_hw_mgr->csid_devices[i];
		rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &csid_acquire,
			sizeof(csid_acquire));
		if (rc)
			continue;
		else
			break;
	}

	if (i == CAM_IFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) {
		CAM_ERR(CAM_ISP, "Can not acquire ife csid rdi resource");
		goto err;
	}

	cid_res->res_type = CAM_IFE_HW_MGR_RES_CID;
	cid_res->res_id = csid_acquire.node_res->res_id;
	cid_res->is_dual_vfe = in_port->usage_type;
	cid_res->hw_res[0] = csid_acquire.node_res;
	cid_res->hw_res[1] = NULL;
	/* CID(DT_ID) value of acquire device, require for path */
	*cid_res_id = csid_acquire.node_res->res_id;

	if (cid_res->is_dual_vfe) {
		csid_acquire.node_res = NULL;
		csid_acquire.res_type = CAM_ISP_RESOURCE_CID;
		csid_acquire.in_port = in_port;
		for (j = i + 1; j < CAM_IFE_CSID_HW_NUM_MAX; j++) {
			if (!ife_hw_mgr->csid_devices[j])
				continue;

			hw_intf = ife_hw_mgr->csid_devices[j];
			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
				&csid_acquire, sizeof(csid_acquire));
			if (rc)
				continue;
			else
				break;
		}

		if (j == CAM_IFE_CSID_HW_NUM_MAX) {
			CAM_ERR(CAM_ISP,
				"Can not acquire ife csid rdi resource");
			goto err;
		}
		cid_res->hw_res[1] = csid_acquire.node_res;
	}
	cid_res->parent = &ife_ctx->res_list_ife_in;
	ife_ctx->res_list_ife_in.child[
		ife_ctx->res_list_ife_in.num_children++] = cid_res;

	return 0;
err:
	return rc;

}
static int cam_ife_mgr_acquire_hw_for_ctx(
	struct cam_ife_hw_mgr_ctx          *ife_ctx,
	struct cam_isp_in_port_info        *in_port,
@@ -1229,7 +1247,6 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
	int is_dual_vfe                           = 0;
	int pixel_count                           = 0;
	int rdi_count                             = 0;
	uint32_t                                cid_res_id = 0;

	is_dual_vfe = in_port->usage_type;

@@ -1248,18 +1265,9 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
		return -EINVAL;
	}

	/* get cid resource */
	rc = cam_ife_mgr_acquire_cid_res(ife_ctx, in_port, &cid_res_id,
		pixel_count);
	if (rc) {
		CAM_ERR(CAM_ISP, "Acquire IFE CID resource Failed");
		goto err;
	}

	if (pixel_count) {
		/* get ife csid IPP resrouce */
		rc = cam_ife_hw_mgr_acquire_res_ife_csid_ipp(ife_ctx, in_port,
				cid_res_id);
		rc = cam_ife_hw_mgr_acquire_res_ife_csid_ipp(ife_ctx, in_port);
		if (rc) {
			CAM_ERR(CAM_ISP,
				"Acquire IFE CSID IPP resource Failed");
@@ -1269,8 +1277,7 @@ static int cam_ife_mgr_acquire_hw_for_ctx(

	if (rdi_count) {
		/* get ife csid rdi resource */
		rc = cam_ife_hw_mgr_acquire_res_ife_csid_rdi(ife_ctx, in_port,
			cid_res_id);
		rc = cam_ife_hw_mgr_acquire_res_ife_csid_rdi(ife_ctx, in_port);
		if (rc) {
			CAM_ERR(CAM_ISP,
				"Acquire IFE CSID RDI resource Failed");
+32 −20
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ static int cam_ife_csid_get_format_ipp(

static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
	struct cam_isp_resource_node **res, int32_t vc, uint32_t dt,
	uint32_t res_type, int pixel_count)
	uint32_t res_type)
{
	int  rc = 0;
	struct cam_ife_csid_cid_data    *cid_data;
@@ -305,8 +305,7 @@ static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
					break;
				}
			} else {
				if (cid_data->vc == vc && cid_data->dt == dt &&
					cid_data->pixel_count == pixel_count) {
				if (cid_data->vc == vc && cid_data->dt == dt) {
					cid_data->cnt++;
					*res = &csid_hw->cid_res[i];
					break;
@@ -330,7 +329,6 @@ static int cam_ife_csid_cid_get(struct cam_ife_csid_hw *csid_hw,
				cid_data->vc  = vc;
				cid_data->dt  = dt;
				cid_data->cnt = 1;
				cid_data->pixel_count = pixel_count;
				csid_hw->cid_res[j].res_state =
					CAM_ISP_RESOURCE_STATE_RESERVED;
				*res = &csid_hw->cid_res[j];
@@ -570,7 +568,6 @@ static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
	struct cam_csid_hw_reserve_resource_args  *cid_reserv)
{
	int rc = 0;
	uint32_t i;
	struct cam_ife_csid_cid_data       *cid_data;

	CAM_DBG(CAM_ISP,
@@ -728,7 +725,6 @@ static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
		cid_data->vc = cid_reserv->in_port->vc;
		cid_data->dt = cid_reserv->in_port->dt;
		cid_data->cnt = 1;
		cid_data->pixel_count = cid_reserv->pixel_count;
		cid_reserv->node_res = &csid_hw->cid_res[0];
		csid_hw->csi2_reserve_cnt++;

@@ -737,27 +733,43 @@ static int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
			csid_hw->hw_intf->hw_idx,
			cid_reserv->node_res->res_id);
	} else {
		if (cid_reserv->pixel_count > 0) {
			for (i = 0; i < CAM_IFE_CSID_CID_RES_MAX; i++) {
				cid_data = (struct cam_ife_csid_cid_data *)
					csid_hw->cid_res[i].res_priv;
				if ((csid_hw->cid_res[i].res_state >=
					CAM_ISP_RESOURCE_STATE_RESERVED) &&
					cid_data->pixel_count > 0) {
		switch (cid_reserv->res_id) {
		case CAM_IFE_PIX_PATH_RES_IPP:
			if (csid_hw->ipp_res.res_state !=
				CAM_ISP_RESOURCE_STATE_AVAILABLE) {
				CAM_DBG(CAM_ISP,
						"CSID:%d IPP resource is full");
					"CSID:%d IPP resource not available",
					csid_hw->hw_intf->hw_idx);
				rc = -EINVAL;
				goto end;
			}
			break;
		case CAM_IFE_PIX_PATH_RES_RDI_0:
		case CAM_IFE_PIX_PATH_RES_RDI_1:
		case CAM_IFE_PIX_PATH_RES_RDI_2:
		case CAM_IFE_PIX_PATH_RES_RDI_3:
			if (csid_hw->rdi_res[cid_reserv->res_id].res_state !=
				CAM_ISP_RESOURCE_STATE_AVAILABLE) {
				CAM_DBG(CAM_ISP,
					"CSID:%d RDI:%d resource not available",
					csid_hw->hw_intf->hw_idx,
					cid_reserv->res_id);
				rc = -EINVAL;
				goto end;
			}
			break;
		default:
			CAM_ERR(CAM_ISP, "CSID%d: Invalid csid path",
				csid_hw->hw_intf->hw_idx);
			rc = -EINVAL;
			goto end;
		}

		rc = cam_ife_csid_cid_get(csid_hw,
			&cid_reserv->node_res,
			cid_reserv->in_port->vc,
			cid_reserv->in_port->dt,
			cid_reserv->in_port->res_type,
			cid_reserv->pixel_count);
			cid_reserv->in_port->res_type);
		/* if success then increment the reserve count */
		if (!rc) {
			if (csid_hw->csi2_reserve_cnt == UINT_MAX) {
+1 −2
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -368,7 +368,6 @@ struct cam_ife_csid_cid_data {
	uint32_t                     dt;
	uint32_t                     cnt;
	uint32_t                     tpg_set;
	int                          pixel_count;
};


+1 −3
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -75,7 +75,6 @@ struct cam_ife_csid_hw_caps {
 * @cid:          cid (DT_ID) value for path, this is applicable for CSID path
 *                reserve
 * @node_res :    Reserved resource structure pointer
 * @pixel_count:  Number of pixel resources
 *
 */
struct cam_csid_hw_reserve_resource_args {
@@ -87,7 +86,6 @@ struct cam_csid_hw_reserve_resource_args {
	uint32_t                                  master_idx;
	uint32_t                                  cid;
	struct cam_isp_resource_node             *node_res;
	int                                       pixel_count;
};

/**