Преглед на файлове

msm: camera: jpeg: Add dma driver implementation

Add code to fill register settings and irq handler code
for JPEG DMA.

CRs-Fixed: 2716356
Change-Id: Ib48c5b27e6b29bf935fff3b68a6c74b483ea572c
Signed-off-by: Suraj Dongre <[email protected]>
Suraj Dongre преди 5 години
родител
ревизия
8210c9c216

+ 129 - 64
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c

@@ -38,6 +38,112 @@ static struct cam_jpeg_hw_mgr g_jpeg_hw_mgr;
 static int32_t cam_jpeg_hw_mgr_cb(uint32_t irq_status,
 	int32_t result_size, void *data);
 static int cam_jpeg_mgr_process_cmd(void *priv, void *data);
+static int cam_jpeg_insert_cdm_change_base(
+	struct cam_hw_config_args *config_args,
+	struct cam_jpeg_hw_ctx_data *ctx_data,
+	struct cam_jpeg_hw_mgr *hw_mgr);
+
+static int cam_jpeg_process_next_hw_update(void *priv, void *data)
+{
+	int rc;
+	int i = 0;
+	struct cam_jpeg_hw_mgr *hw_mgr = priv;
+	struct cam_hw_update_entry *cmd;
+	struct cam_cdm_bl_request *cdm_cmd;
+	struct cam_hw_config_args *config_args = NULL;
+	struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
+	uint32_t dev_type;
+	struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
+	uint32_t cdm_cfg_to_insert = 0;
+
+	if (!data || !priv) {
+		CAM_ERR(CAM_JPEG, "Invalid data");
+		return -EINVAL;
+	}
+
+	ctx_data = (struct cam_jpeg_hw_ctx_data *)data;
+	dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
+	p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
+	config_args = (struct cam_hw_config_args *)&p_cfg_req->hw_cfg_args;
+
+	if (!hw_mgr->devices[dev_type][0]->hw_ops.reset) {
+		CAM_ERR(CAM_JPEG, "op reset null ");
+		rc = -EFAULT;
+		goto end_error;
+	}
+	rc = hw_mgr->devices[dev_type][0]->hw_ops.reset(
+		hw_mgr->devices[dev_type][0]->hw_priv,
+		NULL, 0);
+	if (rc) {
+		CAM_ERR(CAM_JPEG, "jpeg hw reset failed %d", rc);
+		goto end_error;
+	}
+
+	cdm_cmd = ctx_data->cdm_cmd;
+	cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
+	cdm_cmd->flag = false;
+	cdm_cmd->userdata = NULL;
+	cdm_cmd->cookie = 0;
+	cdm_cmd->cmd_arrary_count = 0;
+
+	/* insert cdm chage base cmd */
+	rc = cam_jpeg_insert_cdm_change_base(config_args,
+		ctx_data, hw_mgr);
+	if (rc) {
+		CAM_ERR(CAM_JPEG, "insert change base failed %d", rc);
+		goto end_error;
+	}
+
+	/* insert next cdm payload at index */
+	/* for enc or dma 1st pass at index 1 */
+	/* for dma 2nd pass at index 2, for 3rd at 4 */
+	if (p_cfg_req->num_hw_entry_processed == 0)
+		cdm_cfg_to_insert = CAM_JPEG_CFG;
+	else
+		cdm_cfg_to_insert = p_cfg_req->num_hw_entry_processed + 2;
+
+	CAM_DBG(CAM_JPEG, "processed %d total %d using cfg entry %d for %pK",
+		p_cfg_req->num_hw_entry_processed,
+		config_args->num_hw_update_entries,
+		cdm_cfg_to_insert,
+		p_cfg_req);
+
+	cmd = (config_args->hw_update_entries + cdm_cfg_to_insert);
+	cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle =
+		cmd->handle;
+	cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset =
+		cmd->offset;
+	cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len =
+		cmd->len;
+	CAM_DBG(CAM_JPEG, "i %d entry h %d o %d l %d",
+		i, cmd->handle, cmd->offset, cmd->len);
+	cdm_cmd->cmd_arrary_count++;
+
+	rc = cam_cdm_submit_bls(
+		hw_mgr->cdm_info[dev_type][0].cdm_handle,
+		cdm_cmd);
+	if (rc) {
+		CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", rc);
+		goto end_error;
+	}
+
+	if (!hw_mgr->devices[dev_type][0]->hw_ops.start) {
+		CAM_ERR(CAM_JPEG, "op start null ");
+		rc = -EINVAL;
+		goto end_error;
+	}
+	rc = hw_mgr->devices[dev_type][0]->hw_ops.start(
+		hw_mgr->devices[dev_type][0]->hw_priv, NULL, 0);
+	if (rc) {
+		CAM_ERR(CAM_JPEG, "Failed to apply the configs %d",
+			rc);
+		goto end_error;
+	}
+
+	return 0;
+end_error:
+	return rc;
+}
 
 static int cam_jpeg_mgr_process_irq(void *priv, void *data)
 {
@@ -85,6 +191,21 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
 		return -EINVAL;
 	}
 
+	p_cfg_req->num_hw_entry_processed++;
+	CAM_DBG(CAM_JPEG, "hw entry processed %d",
+		p_cfg_req->num_hw_entry_processed);
+
+	if ((task_data->result_size > 0) &&
+		(p_cfg_req->num_hw_entry_processed <
+			p_cfg_req->hw_cfg_args.num_hw_update_entries - 2)) {
+		/* start processing next entry before marking device free */
+		rc  = cam_jpeg_process_next_hw_update(priv, ctx_data);
+		if (!rc) {
+			mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
+			return 0;
+		}
+	}
+
 	irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
 	irq_cb.data = NULL;
 	irq_cb.b_set_cb = false;
@@ -281,7 +402,9 @@ static int cam_jpeg_insert_cdm_change_base(
 
 	if (config_args->hw_update_entries[CAM_JPEG_CHBASE].offset >=
 		ch_base_len) {
-		CAM_ERR(CAM_JPEG, "Not enough buf");
+		CAM_ERR(CAM_JPEG, "Not enough buf offset %d len %d",
+			config_args->hw_update_entries[CAM_JPEG_CHBASE].offset,
+			ch_base_len);
 		return -EINVAL;
 	}
 	CAM_DBG(CAM_JPEG, "iova %pK len %zu offset %d",
@@ -321,8 +444,6 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
 	int rc;
 	int i = 0;
 	struct cam_jpeg_hw_mgr *hw_mgr = priv;
-	struct cam_hw_update_entry *cmd;
-	struct cam_cdm_bl_request *cdm_cmd;
 	struct cam_hw_config_args *config_args = NULL;
 	struct cam_jpeg_hw_ctx_data *ctx_data = NULL;
 	uintptr_t request_id = 0;
@@ -424,71 +545,13 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
 		goto end_callcb;
 	}
 
-	if (!hw_mgr->devices[dev_type][0]->hw_ops.reset) {
-		CAM_ERR(CAM_JPEG, "op reset null ");
-		rc = -EFAULT;
-		goto end_callcb;
-	}
-	rc = hw_mgr->devices[dev_type][0]->hw_ops.reset(
-		hw_mgr->devices[dev_type][0]->hw_priv,
-		NULL, 0);
-	if (rc) {
-		CAM_ERR(CAM_JPEG, "jpeg hw reset failed %d", rc);
-		goto end_callcb;
-	}
-
-	cdm_cmd = ctx_data->cdm_cmd;
-	cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
-	cdm_cmd->flag = false;
-	cdm_cmd->userdata = NULL;
-	cdm_cmd->cookie = 0;
-	cdm_cmd->cmd_arrary_count = 0;
-	cdm_cmd->gen_irq_arb = false;
-
-	rc = cam_jpeg_insert_cdm_change_base(config_args,
-		ctx_data, hw_mgr);
-	if (rc) {
-		CAM_ERR(CAM_JPEG, "insert change base failed %d", rc);
-		goto end_callcb;
-	}
-
-	CAM_DBG(CAM_JPEG, "num hw up %d", config_args->num_hw_update_entries);
-	for (i = CAM_JPEG_CFG; i < (config_args->num_hw_update_entries - 1);
-		i++) {
-		cmd = (config_args->hw_update_entries + i);
-		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].bl_addr.mem_handle
-			= cmd->handle;
-		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].offset =
-			cmd->offset;
-		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].len =
-			cmd->len;
-		cdm_cmd->cmd[cdm_cmd->cmd_arrary_count].arbitrate =
-			false;
-		CAM_DBG(CAM_JPEG, "i %d entry h %d o %d l %d",
-			i, cmd->handle, cmd->offset, cmd->len);
-		cdm_cmd->cmd_arrary_count++;
-	}
-
-	rc = cam_cdm_submit_bls(
-		hw_mgr->cdm_info[dev_type][0].cdm_handle, cdm_cmd);
+	/* insert one of the cdm payloads */
+	rc = cam_jpeg_process_next_hw_update(priv, ctx_data);
 	if (rc) {
-		CAM_ERR(CAM_JPEG, "Failed to apply the configs %d", rc);
+		CAM_ERR(CAM_JPEG, "next hw update failed %d", rc);
 		goto end_callcb;
 	}
 
-	if (!hw_mgr->devices[dev_type][0]->hw_ops.start) {
-		CAM_ERR(CAM_JPEG, "op start null ");
-		rc = -EINVAL;
-		goto end_callcb;
-	}
-	rc = hw_mgr->devices[dev_type][0]->hw_ops.start(
-		hw_mgr->devices[dev_type][0]->hw_priv,
-		NULL, 0);
-	if (rc) {
-		CAM_ERR(CAM_JPEG, "Failed to start hw %d",
-			rc);
-		goto end_callcb;
-	}
 	p_cfg_req->submit_timestamp = ktime_get();
 
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
@@ -567,6 +630,7 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
 
 	request_id = (uintptr_t)config_args->priv;
 	p_cfg_req->req_id = request_id;
+	p_cfg_req->num_hw_entry_processed = 0;
 	hw_update_entries = config_args->hw_update_entries;
 	CAM_DBG(CAM_JPEG, "ctx_data = %pK req_id = %lld %zd",
 		ctx_data, request_id, (uintptr_t)config_args->priv);
@@ -781,6 +845,7 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
 			i, io_cfg_ptr[i].direction, io_cfg_ptr[i].fence);
 	}
 
+	CAM_DBG(CAM_JPEG, "received num cmd buf %d", packet->num_cmd_buf);
 
 	j = prepare_args->num_hw_update_entries;
 	rc = cam_packet_util_get_kmd_buffer(packet, &kmd_buf);

+ 2 - 0
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h

@@ -76,6 +76,7 @@ struct cam_jpeg_hw_cdm_info_t {
  * @dev_type: Dev type for cfg request
  * @req_id: Request Id
  * @submit_timestamp: Timestamp of submitting request
+ * @num_hw_entry_processed: Cdm payloads already processed
  */
 struct cam_jpeg_hw_cfg_req {
 	struct list_head list;
@@ -83,6 +84,7 @@ struct cam_jpeg_hw_cfg_req {
 	uint32_t dev_type;
 	uintptr_t req_id;
 	ktime_t    submit_timestamp;
+	uint32_t num_hw_entry_processed;
 };
 
 /**

+ 46 - 0
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/cam_jpeg_dma_hw_info_ver_4_2_0.h

@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef CAM_JPEG_DMA_HW_INFO_VER_4_2_0_H
+#define CAM_JPEG_DMA_HW_INFO_VER_4_2_0_H
+
+#define CAM_JPEGDMA_HW_IRQ_STATUS_SESSION_DONE (1 << 0)
+#define CAM_JPEGDMA_HW_IRQ_STATUS_RD_BUF_DONE  (1 << 1)
+#define CAM_JPEGDMA_HW_IRQ_STATUS_WR_BUF_DONE  (1 << 5)
+#define CAM_JPEGDMA_HW_IRQ_STATUS_AXI_HALT     (1 << 9)
+#define CAM_JPEGDMA_HW_IRQ_STATUS_RST_DONE     (1 << 10)
+
+#define CAM_JPEGDMA_HW_MASK_COMP_FRAMEDONE \
+		CAM_JPEGDMA_HW_IRQ_STATUS_SESSION_DONE
+#define CAM_JPEGDMA_HW_MASK_COMP_RESET_ACK \
+		CAM_JPEGDMA_HW_IRQ_STATUS_RST_DONE
+
+static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_hw_info = {
+	.reg_offset = {
+		.hw_version = 0x0,
+		.int_clr = 0x14,
+		.int_status = 0x10,
+		.int_mask = 0x0C,
+		.hw_cmd = 0x1C,
+		.reset_cmd = 0x08,
+		.encode_size = 0x180,
+	},
+	.reg_val = {
+		.int_clr_clearall = 0xFFFFFFFF,
+		.int_mask_disable_all = 0x00000000,
+		.int_mask_enable_all = 0xFFFFFFFF,
+		.hw_cmd_start = 0x00000001,
+		.reset_cmd = 0x32083,
+		.hw_cmd_stop = 0x00000004,
+	},
+	.int_status = {
+		.framedone = CAM_JPEGDMA_HW_MASK_COMP_FRAMEDONE,
+		.resetdone = CAM_JPEGDMA_HW_MASK_COMP_RESET_ACK,
+		.iserror = 0x0,
+		.stopdone = CAM_JPEGDMA_HW_IRQ_STATUS_AXI_HALT,
+	}
+};
+
+#endif /* CAM_JPEG_DMA_HW_INFO_VER_4_2_0_H */

+ 233 - 8
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c

@@ -1,6 +1,6 @@
 // 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/of.h>
@@ -23,6 +23,15 @@
 #include "cam_cpas_api.h"
 #include "cam_debug_util.h"
 
+#define CAM_JPEG_HW_IRQ_IS_FRAME_DONE(jpeg_irq_status, hi) \
+	((jpeg_irq_status) & (hi)->int_status.framedone)
+#define CAM_JPEG_HW_IRQ_IS_RESET_ACK(jpeg_irq_status, hi) \
+	((jpeg_irq_status) & (hi)->int_status.resetdone)
+#define CAM_JPEG_HW_IRQ_IS_STOP_DONE(jpeg_irq_status, hi) \
+	((jpeg_irq_status) & (hi)->int_status.stopdone)
+
+#define CAM_JPEG_DMA_RESET_TIMEOUT msecs_to_jiffies(500)
+
 int cam_jpeg_dma_init_hw(void *device_priv,
 	void *init_hw_args, uint32_t arg_size)
 {
@@ -132,7 +141,7 @@ int cam_jpeg_dma_deinit_hw(void *device_priv,
 
 	rc = cam_jpeg_dma_disable_soc_resources(soc_info);
 	if (rc)
-		CAM_ERR(CAM_JPEG, "soc enable failed %d", rc);
+		CAM_ERR(CAM_JPEG, "soc disable failed %d", rc);
 
 	rc = cam_cpas_stop(core_info->cpas_handle);
 	if (rc)
@@ -143,6 +152,226 @@ int cam_jpeg_dma_deinit_hw(void *device_priv,
 	return 0;
 }
 
+irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data)
+{
+	struct cam_hw_info *jpeg_dma_dev = data;
+	struct cam_jpeg_dma_device_core_info *core_info = NULL;
+	uint32_t irq_status = 0;
+	struct cam_hw_soc_info *soc_info = NULL;
+	struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
+	void __iomem *mem_base;
+
+	if (!jpeg_dma_dev) {
+		CAM_ERR(CAM_JPEG, "Invalid args");
+		return IRQ_HANDLED;
+	}
+	soc_info = &jpeg_dma_dev->soc_info;
+	core_info = (struct cam_jpeg_dma_device_core_info *)
+		jpeg_dma_dev->core_info;
+	hw_info = core_info->jpeg_dma_hw_info;
+	mem_base = soc_info->reg_map[0].mem_base;
+
+	irq_status = cam_io_r_mb(mem_base +
+		core_info->jpeg_dma_hw_info->reg_offset.int_status);
+	cam_io_w_mb(irq_status,
+		soc_info->reg_map[0].mem_base +
+		core_info->jpeg_dma_hw_info->reg_offset.int_clr);
+	CAM_DBG(CAM_JPEG, "irq_num %d  irq_status = %x , core_state %d",
+		irq_num, irq_status, core_info->core_state);
+	if (CAM_JPEG_HW_IRQ_IS_FRAME_DONE(irq_status, hw_info)) {
+		spin_lock(&jpeg_dma_dev->hw_lock);
+		if (core_info->core_state == CAM_JPEG_DMA_CORE_READY) {
+			core_info->result_size = 1;
+			CAM_DBG(CAM_JPEG, "result_size %d",
+				core_info->result_size);
+			core_info->core_state =
+				CAM_JPEG_DMA_CORE_RESETTING_ON_DONE;
+			cam_io_w_mb(hw_info->reg_val.reset_cmd,
+				mem_base + hw_info->reg_offset.reset_cmd);
+		} else {
+			CAM_WARN(CAM_JPEG, "unexpected frame done ");
+			core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
+		}
+		spin_unlock(&jpeg_dma_dev->hw_lock);
+	}
+
+	if (CAM_JPEG_HW_IRQ_IS_RESET_ACK(irq_status, hw_info)) {
+		spin_lock(&jpeg_dma_dev->hw_lock);
+		if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) {
+			core_info->core_state = CAM_JPEG_DMA_CORE_READY;
+			core_info->result_size = -1;
+			complete(&jpeg_dma_dev->hw_complete);
+		} else if (core_info->core_state ==
+			CAM_JPEG_DMA_CORE_RESETTING_ON_DONE) {
+			if (core_info->irq_cb.jpeg_hw_mgr_cb) {
+				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
+					core_info->result_size,
+					core_info->irq_cb.data);
+			} else {
+				CAM_WARN(CAM_JPEG, "unexpected frame done");
+			}
+			core_info->result_size = -1;
+			core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
+		} else {
+			CAM_ERR(CAM_JPEG, "unexpected reset irq");
+		}
+		spin_unlock(&jpeg_dma_dev->hw_lock);
+	}
+	if (CAM_JPEG_HW_IRQ_IS_STOP_DONE(irq_status, hw_info)) {
+		spin_lock(&jpeg_dma_dev->hw_lock);
+		if (core_info->core_state == CAM_JPEG_DMA_CORE_ABORTING) {
+			core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
+			complete(&jpeg_dma_dev->hw_complete);
+			if (core_info->irq_cb.jpeg_hw_mgr_cb) {
+				core_info->irq_cb.jpeg_hw_mgr_cb(irq_status,
+					-1,
+					core_info->irq_cb.data);
+			}
+		} else {
+			CAM_ERR(CAM_JPEG, "unexpected abort irq");
+		}
+		spin_unlock(&jpeg_dma_dev->hw_lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+int cam_jpeg_dma_reset_hw(void *data,
+	void *start_args, uint32_t arg_size)
+{
+	struct cam_hw_info *jpeg_dma_dev = data;
+	struct cam_jpeg_dma_device_core_info *core_info = NULL;
+	struct cam_hw_soc_info *soc_info = NULL;
+	struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
+	void __iomem *mem_base;
+	unsigned long rem_jiffies;
+
+	if (!jpeg_dma_dev) {
+		CAM_ERR(CAM_JPEG, "Invalid args");
+		return -EINVAL;
+	}
+	/* maskdisable.clrirq.maskenable.resetcmd */
+	soc_info = &jpeg_dma_dev->soc_info;
+	core_info = (struct cam_jpeg_dma_device_core_info *)
+		jpeg_dma_dev->core_info;
+	hw_info = core_info->jpeg_dma_hw_info;
+	mem_base = soc_info->reg_map[0].mem_base;
+
+	mutex_lock(&core_info->core_mutex);
+	spin_lock(&jpeg_dma_dev->hw_lock);
+	if (core_info->core_state == CAM_JPEG_DMA_CORE_RESETTING) {
+		CAM_ERR(CAM_JPEG, "dma alrady resetting");
+		spin_unlock(&jpeg_dma_dev->hw_lock);
+		mutex_unlock(&core_info->core_mutex);
+		return 0;
+	}
+
+	reinit_completion(&jpeg_dma_dev->hw_complete);
+
+	core_info->core_state = CAM_JPEG_DMA_CORE_RESETTING;
+	spin_unlock(&jpeg_dma_dev->hw_lock);
+
+	cam_io_w_mb(hw_info->reg_val.int_mask_disable_all,
+		mem_base + hw_info->reg_offset.int_mask);
+	cam_io_w_mb(hw_info->reg_val.int_clr_clearall,
+		mem_base + hw_info->reg_offset.int_clr);
+	cam_io_w_mb(hw_info->reg_val.int_mask_enable_all,
+		mem_base + hw_info->reg_offset.int_mask);
+	cam_io_w_mb(hw_info->reg_val.reset_cmd,
+		mem_base + hw_info->reg_offset.reset_cmd);
+
+	rem_jiffies = wait_for_completion_timeout(&jpeg_dma_dev->hw_complete,
+		CAM_JPEG_DMA_RESET_TIMEOUT);
+	if (!rem_jiffies) {
+		CAM_ERR(CAM_JPEG, "dma error Reset Timeout");
+		core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
+	}
+
+	mutex_unlock(&core_info->core_mutex);
+	return 0;
+}
+
+int cam_jpeg_dma_start_hw(void *data,
+	void *start_args, uint32_t arg_size)
+{
+	struct cam_hw_info *jpeg_dma_dev = data;
+	struct cam_jpeg_dma_device_core_info *core_info = NULL;
+	struct cam_hw_soc_info *soc_info = NULL;
+	struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
+	void __iomem *mem_base;
+
+	if (!jpeg_dma_dev) {
+		CAM_ERR(CAM_JPEG, "Invalid args");
+		return -EINVAL;
+	}
+
+	soc_info = &jpeg_dma_dev->soc_info;
+	core_info = (struct cam_jpeg_dma_device_core_info *)
+		jpeg_dma_dev->core_info;
+	hw_info = core_info->jpeg_dma_hw_info;
+	mem_base = soc_info->reg_map[0].mem_base;
+
+	if (core_info->core_state != CAM_JPEG_DMA_CORE_READY) {
+		CAM_ERR(CAM_JPEG, "Error not ready");
+		return -EINVAL;
+	}
+
+	CAM_DBG(CAM_JPEG, "Starting DMA");
+	cam_io_w_mb(0x00000601,
+		mem_base + hw_info->reg_offset.int_mask);
+	cam_io_w_mb(hw_info->reg_val.hw_cmd_start,
+		mem_base + hw_info->reg_offset.hw_cmd);
+
+	return 0;
+}
+
+int cam_jpeg_dma_stop_hw(void *data,
+	void *stop_args, uint32_t arg_size)
+{
+	struct cam_hw_info *jpeg_dma_dev = data;
+	struct cam_jpeg_dma_device_core_info *core_info = NULL;
+	struct cam_hw_soc_info *soc_info = NULL;
+	struct cam_jpeg_dma_device_hw_info *hw_info = NULL;
+	void __iomem *mem_base;
+	unsigned long rem_jiffies;
+
+	if (!jpeg_dma_dev) {
+		CAM_ERR(CAM_JPEG, "Invalid args");
+		return -EINVAL;
+	}
+	soc_info = &jpeg_dma_dev->soc_info;
+	core_info = (struct cam_jpeg_dma_device_core_info *)
+		jpeg_dma_dev->core_info;
+	hw_info = core_info->jpeg_dma_hw_info;
+	mem_base = soc_info->reg_map[0].mem_base;
+
+	mutex_lock(&core_info->core_mutex);
+	spin_lock(&jpeg_dma_dev->hw_lock);
+	if (core_info->core_state == CAM_JPEG_DMA_CORE_ABORTING) {
+		CAM_ERR(CAM_JPEG, "alrady stopping");
+		spin_unlock(&jpeg_dma_dev->hw_lock);
+		mutex_unlock(&core_info->core_mutex);
+		return 0;
+	}
+
+	reinit_completion(&jpeg_dma_dev->hw_complete);
+	core_info->core_state = CAM_JPEG_DMA_CORE_ABORTING;
+	spin_unlock(&jpeg_dma_dev->hw_lock);
+
+	cam_io_w_mb(hw_info->reg_val.hw_cmd_stop,
+		mem_base + hw_info->reg_offset.hw_cmd);
+
+	rem_jiffies = wait_for_completion_timeout(&jpeg_dma_dev->hw_complete,
+		CAM_JPEG_DMA_RESET_TIMEOUT);
+	if (!rem_jiffies) {
+		CAM_ERR(CAM_JPEG, "error Reset Timeout");
+		core_info->core_state = CAM_JPEG_DMA_CORE_NOT_READY;
+	}
+
+	mutex_unlock(&core_info->core_mutex);
+	return 0;
+}
+
 int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
 	void *cmd_args, uint32_t arg_size)
 {
@@ -187,11 +416,7 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = -EINVAL;
 		break;
 	}
-
+	if (rc)
+		CAM_ERR(CAM_JPEG, "error cmdtype %d rc = %d", cmd_type, rc);
 	return rc;
 }
-
-irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data)
-{
-	return IRQ_HANDLED;
-}

+ 40 - 2
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h

@@ -1,6 +1,6 @@
 /* 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_JPEG_DMA_CORE_H
@@ -10,17 +10,48 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/dma-buf.h>
 
 #include "cam_jpeg_hw_intf.h"
 
+struct cam_jpeg_dma_reg_offsets {
+	uint32_t hw_version;
+	uint32_t int_status;
+	uint32_t int_clr;
+	uint32_t int_mask;
+	uint32_t hw_cmd;
+	uint32_t reset_cmd;
+	uint32_t encode_size;
+};
+
+struct cam_jpeg_dma_regval {
+	uint32_t int_clr_clearall;
+	uint32_t int_mask_disable_all;
+	uint32_t int_mask_enable_all;
+	uint32_t hw_cmd_start;
+	uint32_t reset_cmd;
+	uint32_t hw_cmd_stop;
+};
+
+struct cam_jpeg_dma_int_status {
+	uint32_t framedone;
+	uint32_t resetdone;
+	uint32_t iserror;
+	uint32_t stopdone;
+};
+
 struct cam_jpeg_dma_device_hw_info {
-	uint32_t reserved;
+	struct cam_jpeg_dma_reg_offsets reg_offset;
+	struct cam_jpeg_dma_regval reg_val;
+	struct cam_jpeg_dma_int_status int_status;
 };
 
 enum cam_jpeg_dma_core_state {
 	CAM_JPEG_DMA_CORE_NOT_READY,
 	CAM_JPEG_DMA_CORE_READY,
 	CAM_JPEG_DMA_CORE_RESETTING,
+	CAM_JPEG_DMA_CORE_ABORTING,
+	CAM_JPEG_DMA_CORE_RESETTING_ON_DONE,
 	CAM_JPEG_DMA_CORE_STATE_MAX,
 };
 
@@ -31,12 +62,19 @@ struct cam_jpeg_dma_device_core_info {
 	struct cam_jpeg_set_irq_cb irq_cb;
 	int32_t ref_count;
 	struct mutex core_mutex;
+	int32_t result_size;
 };
 
 int cam_jpeg_dma_init_hw(void *device_priv,
 	void *init_hw_args, uint32_t arg_size);
 int cam_jpeg_dma_deinit_hw(void *device_priv,
 	void *init_hw_args, uint32_t arg_size);
+int cam_jpeg_dma_start_hw(void *device_priv,
+	void *start_hw_args, uint32_t arg_size);
+int cam_jpeg_dma_stop_hw(void *device_priv,
+	void *stop_hw_args, uint32_t arg_size);
+int cam_jpeg_dma_reset_hw(void *device_priv,
+	void *reset_hw_args, uint32_t arg_size);
 int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type,
 	void *cmd_args, uint32_t arg_size);
 irqreturn_t cam_jpeg_dma_irq(int irq_num, void *data);

+ 7 - 11
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c

@@ -18,12 +18,9 @@
 #include "cam_jpeg_hw_mgr_intf.h"
 #include "cam_cpas_api.h"
 #include "cam_debug_util.h"
+#include "cam_jpeg_dma_hw_info_ver_4_2_0.h"
 #include "camera_main.h"
 
-static struct cam_jpeg_dma_device_hw_info cam_jpeg_dma_hw_info = {
-	.reserved = 0,
-};
-
 static int cam_jpeg_dma_register_cpas(struct cam_hw_soc_info *soc_info,
 	struct cam_jpeg_dma_device_core_info *core_info,
 	uint32_t hw_idx)
@@ -90,6 +87,9 @@ static int cam_jpeg_dma_component_bind(struct device *dev,
 	jpeg_dma_dev_intf->hw_priv = jpeg_dma_dev;
 	jpeg_dma_dev_intf->hw_ops.init = cam_jpeg_dma_init_hw;
 	jpeg_dma_dev_intf->hw_ops.deinit = cam_jpeg_dma_deinit_hw;
+	jpeg_dma_dev_intf->hw_ops.start = cam_jpeg_dma_start_hw;
+	jpeg_dma_dev_intf->hw_ops.stop = cam_jpeg_dma_stop_hw;
+	jpeg_dma_dev_intf->hw_ops.reset = cam_jpeg_dma_reset_hw;
 	jpeg_dma_dev_intf->hw_ops.process_cmd = cam_jpeg_dma_process_cmd;
 	jpeg_dma_dev_intf->hw_type = CAM_JPEG_DEV_DMA;
 
@@ -134,14 +134,11 @@ static int cam_jpeg_dma_component_bind(struct device *dev,
 	mutex_init(&jpeg_dma_dev->hw_mutex);
 	spin_lock_init(&jpeg_dma_dev->hw_lock);
 	init_completion(&jpeg_dma_dev->hw_complete);
-
-	CAM_DBG(CAM_JPEG, "JPEG:%d component bound successfully",
-		jpeg_dma_dev_intf->hw_idx);
-
+	CAM_DBG(CAM_JPEG, "JPEG-DMA component bound successfully");
 	return rc;
 
 error_reg_cpas:
-	rc = cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info);
+	cam_soc_util_release_platform_resource(&jpeg_dma_dev->soc_info);
 error_init_soc:
 	mutex_destroy(&core_info->core_mutex);
 error_match_dev:
@@ -150,6 +147,7 @@ error_alloc_core:
 	kfree(jpeg_dma_dev);
 error_alloc_dev:
 	kfree(jpeg_dma_dev_intf);
+
 	return rc;
 }
 
@@ -198,8 +196,6 @@ deinit_soc:
 
 free_jpeg_hw_intf:
 	kfree(jpeg_dma_dev_intf);
-	return;
-
 }
 
 const static struct component_ops cam_jpeg_dma_component_ops = {

+ 1 - 0
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c

@@ -356,6 +356,7 @@ int cam_jpeg_enc_start_hw(void *data,
 	}
 	spin_unlock_irqrestore(&jpeg_enc_dev->hw_lock, flags);
 
+	CAM_DBG(CAM_JPEG, "Starting JPEG ENC");
 	cam_io_w_mb(hw_info->reg_val.hw_cmd_start,
 		mem_base + hw_info->reg_offset.hw_cmd);
 

+ 1 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c

@@ -134,7 +134,7 @@ static int cam_jpeg_enc_component_bind(struct device *dev,
 	mutex_init(&jpeg_enc_dev->hw_mutex);
 	spin_lock_init(&jpeg_enc_dev->hw_lock);
 	init_completion(&jpeg_enc_dev->hw_complete);
-	CAM_DBG(CAM_JPEG, "Encoder component bound successfully");
+	CAM_DBG(CAM_JPEG, "JPEG-Encoder component bound successfully");
 
 	return rc;