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

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

Merge "msm: camera: ope: Put GenIRQ in last stripe BL" into camera-kernel.lnx.3.1

parents 9f1ead85 259fc2c9
Loading
Loading
Loading
Loading
+46 −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/delay.h>
@@ -262,6 +262,47 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
	}
}

static int cam_cdm_stream_handle_init(void *hw_priv, bool init)
{
	struct cam_hw_info *cdm_hw = hw_priv;
	struct cam_cdm *core = NULL;
	int rc = -EPERM;

	core = (struct cam_cdm *)cdm_hw->core_info;

	if (init) {
		rc = cam_hw_cdm_init(hw_priv, NULL, 0);
		if (rc) {
			CAM_ERR(CAM_CDM, "CDM HW init failed");
			return rc;
		}

		if (core->arbitration !=
			CAM_CDM_ARBITRATION_PRIORITY_BASED) {
			rc = cam_hw_cdm_alloc_genirq_mem(
				hw_priv);
			if (rc) {
				CAM_ERR(CAM_CDM,
					"Genirqalloc failed");
				cam_hw_cdm_deinit(hw_priv,
					NULL, 0);
			}
		}
	} else {
		rc = cam_hw_cdm_deinit(hw_priv, NULL, 0);
		if (rc)
			CAM_ERR(CAM_CDM, "Deinit failed in streamoff");

		if (core->arbitration !=
			CAM_CDM_ARBITRATION_PRIORITY_BASED) {
			if (cam_hw_cdm_release_genirq_mem(hw_priv))
				CAM_ERR(CAM_CDM, "Genirq release fail");
		}
	}

	return rc;
}

int cam_cdm_stream_ops_internal(void *hw_priv,
	void *start_args, bool operation)
{
@@ -337,19 +378,7 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
				rc = 0;
			} else {
				CAM_DBG(CAM_CDM, "CDM HW init first time");
				rc = cam_hw_cdm_init(hw_priv, NULL, 0);
				if (rc == 0) {
					rc = cam_hw_cdm_alloc_genirq_mem(
						hw_priv);
					if (rc != 0) {
						CAM_ERR(CAM_CDM,
							"Genirqalloc failed");
						cam_hw_cdm_deinit(hw_priv,
							NULL, 0);
					}
				} else {
					CAM_ERR(CAM_CDM, "CDM HW init failed");
				}
				rc = cam_cdm_stream_handle_init(hw_priv, true);
			}
			if (rc == 0) {
				cdm_hw->open_count++;
@@ -378,17 +407,10 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
					rc = 0;
				} else {
					CAM_DBG(CAM_CDM, "CDM HW Deinit now");
					rc = cam_hw_cdm_deinit(
						hw_priv, NULL, 0);
					if (cam_hw_cdm_release_genirq_mem(
						hw_priv))
						CAM_ERR(CAM_CDM,
							"Genirq release fail");
					rc = cam_cdm_stream_handle_init(hw_priv,
						false);
				}
				if (rc) {
					CAM_ERR(CAM_CDM,
						"Deinit failed in streamoff");
				} else {
				if (rc == 0) {
					client->stream_on = false;
					rc = cam_cpas_stop(core->cpas_handle);
					if (rc)
+131 −27
Original line number Diff line number Diff line
@@ -738,6 +738,78 @@ int cam_hw_cdm_submit_debug_gen_irq(
	return rc;
}

static int cam_hw_cdm_arb_submit_bl(struct cam_hw_info *cdm_hw,
	struct cam_cdm_hw_intf_cmd_submit_bl *req, int i,
	uint32_t fifo_idx, dma_addr_t hw_vaddr_ptr)
{
	struct cam_cdm_bl_request *cdm_cmd = req->data;
	struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
	uintptr_t cpu_addr;
	struct cam_cdm_bl_cb_request_entry *node;
	int rc = 0;
	size_t len = 0;

	node = kzalloc(sizeof(
		struct cam_cdm_bl_cb_request_entry),
		GFP_KERNEL);
	if (!node)
		return -ENOMEM;

	node->request_type = CAM_HW_CDM_BL_CB_CLIENT;
	node->client_hdl = req->handle;
	node->cookie = req->data->cookie;
	node->bl_tag = core->bl_fifo[fifo_idx].bl_tag -
		1;
	node->userdata = req->data->userdata;
	list_add_tail(&node->entry,
		&core->bl_fifo[fifo_idx]
		.bl_request_list);
	cdm_cmd->cmd[i].arbitrate = 1;
	rc = cam_mem_get_cpu_buf(
		cdm_cmd->cmd[i].bl_addr.mem_handle,
		&cpu_addr, &len);
	if (rc || !cpu_addr) {
		CAM_ERR(CAM_OPE, "get cmd buffailed %x",
			cdm_cmd->cmd[i].bl_addr
			.mem_handle);
		return rc;
	}
	core->ops->cdm_write_genirq(
		((uint32_t *)cpu_addr +
		cdm_cmd->cmd[i].offset / 4 +
		cdm_cmd->cmd[i].len / 4),
		core->bl_fifo[fifo_idx].bl_tag - 1,
		1, fifo_idx);
	rc = cam_hw_cdm_bl_write(cdm_hw,
		(uint32_t)hw_vaddr_ptr +
		cdm_cmd->cmd[i].offset,
		cdm_cmd->cmd[i].len + 7,
		core->bl_fifo[fifo_idx].bl_tag - 1,
		1, fifo_idx);
	if (rc) {
		CAM_ERR(CAM_CDM,
			"CDM hw bl write failed tag=%d",
			core->bl_fifo[fifo_idx].bl_tag -
			1);
			list_del_init(&node->entry);
			kfree(node);
			return -EIO;
	}
	rc = cam_hw_cdm_commit_bl_write(cdm_hw,
		fifo_idx);
	if (rc) {
		CAM_ERR(CAM_CDM,
			"CDM hw commit failed tag=%d",
			core->bl_fifo[fifo_idx].bl_tag -
			1);
			list_del_init(&node->entry);
			kfree(node);
			return -EIO;
	}

	return 0;
}

int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
	struct cam_cdm_hw_intf_cmd_submit_bl *req,
	struct cam_cdm_client *client)
@@ -867,6 +939,14 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
			if (core->bl_fifo[fifo_idx].bl_tag >=
				(bl_fifo->bl_depth - 1))
				core->bl_fifo[fifo_idx].bl_tag = 0;
			if (core->arbitration ==
				CAM_CDM_ARBITRATION_PRIORITY_BASED &&
				(req->data->flag == true) &&
				(i == (req->data->cmd_arrary_count -
				1))) {
				CAM_DBG(CAM_CDM,
					"GenIRQ in same bl, will sumbit later");
			} else {
				rc = cam_hw_cdm_bl_write(cdm_hw,
					((uint32_t)hw_vaddr_ptr +
						cdm_cmd->cmd[i].offset),
@@ -875,11 +955,13 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
					cdm_cmd->cmd[i].arbitrate,
					fifo_idx);
				if (rc) {
				CAM_ERR(CAM_CDM, "Hw bl write failed %d:%d",
					CAM_ERR(CAM_CDM,
						"Hw bl write failed %d:%d",
						i, req->data->cmd_arrary_count);
					rc = -EIO;
					break;
				}
			}
		} else {
			CAM_ERR(CAM_CDM,
				"Sanity check failed for hdl=%x len=%zu:%d",
@@ -893,20 +975,31 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,

		if (!rc) {
			CAM_DBG(CAM_CDM,
				"write BL success for cnt=%d with tag=%d total_cnt=%d",
				"write BL done cnt=%d with tag=%d total_cnt=%d",
				i, core->bl_fifo[fifo_idx].bl_tag,
				req->data->cmd_arrary_count);

			if (core->arbitration ==
				CAM_CDM_ARBITRATION_PRIORITY_BASED &&
				(req->data->flag == true) &&
				(i == (req->data->cmd_arrary_count -
				1))) {
				CAM_DBG(CAM_CDM,
					"GenIRQ in same blcommit later");
			} else {
				CAM_DBG(CAM_CDM, "Now commit the BL");
			if (cam_hw_cdm_commit_bl_write(cdm_hw, fifo_idx)) {
				if (cam_hw_cdm_commit_bl_write(cdm_hw,
					fifo_idx)) {
					CAM_ERR(CAM_CDM,
					"Cannot commit the BL %d tag=%d",
					i, core->bl_fifo[fifo_idx].bl_tag);
						"commit failed BL %d tag=%d",
						i, core->bl_fifo[fifo_idx]
						.bl_tag);
					rc = -EIO;
					break;
				}
			CAM_DBG(CAM_CDM, "BL commit success BL %d tag=%d", i,
					core->bl_fifo[fifo_idx].bl_tag);
				CAM_DBG(CAM_CDM, "commit success BL %d tag=%d",
					i, core->bl_fifo[fifo_idx].bl_tag);
			}
			core->bl_fifo[fifo_idx].bl_tag++;

			if (cdm_cmd->cmd[i].enable_debug_gen_irq) {
@@ -923,11 +1016,21 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
			if ((req->data->flag == true) &&
				(i == (req->data->cmd_arrary_count -
				1))) {
				if (core->arbitration !=
					CAM_CDM_ARBITRATION_PRIORITY_BASED) {
					rc = cam_hw_cdm_submit_gen_irq(
						cdm_hw, req, fifo_idx,
						cdm_cmd->gen_irq_arb);
					if (rc == 0)
					core->bl_fifo[fifo_idx].bl_tag++;
						core->bl_fifo[fifo_idx]
						.bl_tag++;
					break;
				}

				rc = cam_hw_cdm_arb_submit_bl(cdm_hw, req, i,
					fifo_idx, hw_vaddr_ptr);
				if (rc)
					break;
			}
		}
	}
@@ -972,6 +1075,7 @@ static void cam_hw_cdm_reset_cleanup(
			node = NULL;
		}
		core->bl_fifo[i].bl_tag = 0;
		core->bl_fifo[i].last_bl_tag_done = -1;
	}
}

@@ -1589,7 +1693,7 @@ int cam_hw_cdm_init(void *hw_priv,
		reinit_completion(&cdm_core->bl_fifo[i].bl_complete);
	}
	for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
		cdm_core->bl_fifo[i].last_bl_tag_done = 0;
		cdm_core->bl_fifo[i].last_bl_tag_done = -1;

	rc = cam_hw_cdm_reset_hw(cdm_hw, reset_hw_hdl);

+2 −0
Original line number Diff line number Diff line
@@ -2028,6 +2028,8 @@ static int cam_ope_mgr_process_cmd_buf_req(struct cam_ope_hw_mgr *hw_mgr,
					ope_request->ope_kmd_buf.iova_cdm_addr =
						iova_cdm_addr;
					ope_request->ope_kmd_buf.len = len;
					ope_request->ope_kmd_buf.offset =
						cmd_buf->offset;
					ope_request->ope_kmd_buf.size =
						cmd_buf->size;
					is_kmd_buf_valid = true;
+2 −0
Original line number Diff line number Diff line
@@ -242,6 +242,7 @@ struct ope_debug_buffer {
 * @cpu_addr:         CPU address
 * @iova_addr:        IOVA address
 * @iova_cdm_addr:    CDM IOVA address
 * @offset:           Offset of buffer
 * @len:              Buffer length
 * @size:             Buffer Size
 */
@@ -250,6 +251,7 @@ struct ope_kmd_buffer {
	uintptr_t cpu_addr;
	dma_addr_t iova_addr;
	dma_addr_t iova_cdm_addr;
	uint32_t offset;
	size_t len;
	uint32_t size;
};
+6 −4
Original line number Diff line number Diff line
@@ -380,16 +380,17 @@ static int cam_ope_dev_prepare_cdm_request(
	kmd_buf = (uint32_t *)ope_request->ope_kmd_buf.cpu_addr +
		kmd_buf_offset;

	cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_HW_IOVA;
	cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
	cdm_cmd->flag = true;
	cdm_cmd->userdata = ctx_data;
	cdm_cmd->cookie = req_idx;
	cdm_cmd->gen_irq_arb = true;

	i = cdm_cmd->cmd_arrary_count;
	cdm_cmd->cmd[i].bl_addr.hw_iova =
		(uint32_t *)ope_request->ope_kmd_buf.iova_cdm_addr;
	cdm_cmd->cmd[i].offset = kmd_buf_offset;
	cdm_cmd->cmd[i].bl_addr.mem_handle =
		ope_request->ope_kmd_buf.mem_handle;
	cdm_cmd->cmd[i].offset = kmd_buf_offset +
		ope_request->ope_kmd_buf.offset;
	cdm_cmd->cmd[i].len = len;
	cdm_cmd->cmd[i].arbitrate = arbitrate;

@@ -405,6 +406,7 @@ static int cam_ope_dev_prepare_cdm_request(
	return 0;
}


static int dump_dmi_cmd(uint32_t print_idx,
	uint32_t *print_ptr, struct cdm_dmi_cmd *dmi_cmd,
	uint32_t *temp)