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

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

Merge "msm: camera: jpeg: Add stop device in jpeg context" into dev/msm-4.9-camx

parents 870305ba bb292429
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -63,6 +63,20 @@ static int __cam_jpeg_ctx_handle_buf_done_in_acquired(void *ctx,
	return cam_context_buf_done_from_hw(ctx, done, evt_id);
}

static int __cam_jpeg_ctx_stop_dev_in_acquired(struct cam_context *ctx,
	struct cam_start_stop_dev_cmd *cmd)
{
	int rc;

	rc = cam_context_stop_dev_to_hw(ctx);
	if (rc) {
		CAM_ERR(CAM_JPEG, "Failed in Stop dev, rc=%d", rc);
		return rc;
	}

	return rc;
}

/* top state machine */
static struct cam_ctx_ops
	cam_jpeg_ctx_state_machine[CAM_CTX_STATE_MAX] = {
@@ -85,6 +99,7 @@ static struct cam_ctx_ops
		.ioctl_ops = {
			.release_dev = __cam_jpeg_ctx_release_dev_in_acquired,
			.config_dev = __cam_jpeg_ctx_config_dev_in_acquired,
			.stop_dev = __cam_jpeg_ctx_stop_dev_in_acquired,
		},
		.crm_ops = { },
		.irq_ops = __cam_jpeg_ctx_handle_buf_done_in_acquired,
+104 −6
Original line number Diff line number Diff line
@@ -80,11 +80,23 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)

	dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;

	mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex);

	p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];

	if (hw_mgr->device_in_use[dev_type][0] == false ||
		p_cfg_req == NULL) {
		CAM_ERR(CAM_JPEG, "irq for old request %d", rc);
		mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
		return -EINVAL;
	}

	irq_cb.jpeg_hw_mgr_cb = cam_jpeg_hw_mgr_cb;
	irq_cb.data = NULL;
	irq_cb.b_set_cb = false;
	if (!hw_mgr->devices[dev_type][0]->hw_ops.process_cmd) {
		CAM_ERR(CAM_JPEG, "process_cmd null ");
		mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
		return -EINVAL;
	}
	rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd(
@@ -93,6 +105,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
		&irq_cb, sizeof(irq_cb));
	if (rc) {
		CAM_ERR(CAM_JPEG, "CMD_SET_IRQ_CB failed %d", rc);
		mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);
		return rc;
	}

@@ -103,9 +116,7 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
			CAM_ERR(CAM_JPEG, "Failed to Deinit %d HW", dev_type);
	}

	mutex_lock(&g_jpeg_hw_mgr.hw_mgr_mutex);
	hw_mgr->device_in_use[dev_type][0] = false;
	p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
	hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL;
	mutex_unlock(&g_jpeg_hw_mgr.hw_mgr_mutex);

@@ -167,7 +178,6 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)

	list_add_tail(&p_cfg_req->list, &hw_mgr->free_req_list);


	return rc;
}

@@ -319,8 +329,11 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
		return -EINVAL;
	}

	mutex_lock(&hw_mgr->hw_mgr_mutex);

	if (list_empty(&hw_mgr->hw_config_req_list)) {
		CAM_DBG(CAM_JPEG, "no available request");
		mutex_unlock(&hw_mgr->hw_mgr_mutex);
		rc = -EFAULT;
		goto end;
	}
@@ -329,11 +342,11 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
		struct cam_jpeg_hw_cfg_req, list);
	if (!p_cfg_req) {
		CAM_ERR(CAM_JPEG, "no request");
		mutex_unlock(&hw_mgr->hw_mgr_mutex);
		rc = -EFAULT;
		goto end;
	}

	mutex_lock(&hw_mgr->hw_mgr_mutex);
	if (false == hw_mgr->device_in_use[p_cfg_req->dev_type][0]) {
		hw_mgr->device_in_use[p_cfg_req->dev_type][0] = true;
		hw_mgr->dev_hw_cfg_args[p_cfg_req->dev_type][0] = p_cfg_req;
@@ -344,6 +357,7 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
		rc = -EFAULT;
		goto end;
	}

	mutex_unlock(&hw_mgr->hw_mgr_mutex);

	config_args = (struct cam_hw_config_args *)&p_cfg_req->hw_cfg_args;
@@ -464,7 +478,7 @@ static int cam_jpeg_mgr_process_cmd(void *priv, void *data)
		hw_mgr->devices[dev_type][0]->hw_priv,
		NULL, 0);
	if (rc) {
		CAM_ERR(CAM_JPEG, "Failed to apply the configs %d",
		CAM_ERR(CAM_JPEG, "Failed to start hw %d",
			rc);
		goto end_callcb;
	}
@@ -553,12 +567,12 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
		goto err_after_dq_free_list;
	}

	mutex_unlock(&hw_mgr->hw_mgr_mutex);

	task_data = (struct cam_jpeg_process_frame_work_data_t *)
		task->payload;
	if (!task_data) {
		CAM_ERR(CAM_JPEG, "task_data is NULL");
		mutex_unlock(&hw_mgr->hw_mgr_mutex);
		rc = -EINVAL;
		goto err_after_dq_free_list;
	}
@@ -567,6 +581,7 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
		p_cfg_req->hw_cfg_args.num_hw_update_entries);

	list_add_tail(&p_cfg_req->list, &hw_mgr->hw_config_req_list);
	mutex_unlock(&hw_mgr->hw_mgr_mutex);

	task_data->data = (void *)(int64_t)p_cfg_req->dev_type;
	task_data->request_id = request_id;
@@ -719,6 +734,88 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
	return rc;
}

static int cam_jpeg_mgr_flush(void *hw_mgr_priv,
	struct cam_jpeg_hw_ctx_data *ctx_data)
{
	int rc = 0;
	struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv;
	uint32_t dev_type;
	struct cam_jpeg_hw_cfg_req *p_cfg_req = NULL;
	struct cam_jpeg_hw_cfg_req *cfg_req, *req_temp;

	if (!hw_mgr || !ctx_data) {
		CAM_ERR(CAM_JPEG, "Invalid args");
		return -EINVAL;
	}

	dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;

	p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
	if (hw_mgr->device_in_use[dev_type][0] == true &&
		p_cfg_req != NULL) {
		if ((struct cam_jpeg_hw_ctx_data *)p_cfg_req->
		hw_cfg_args.ctxt_to_hw_map == ctx_data) {
			/* stop reset Unregister CB and deinit */
			if (hw_mgr->devices[dev_type][0]->hw_ops.stop) {
				rc = hw_mgr->devices[dev_type][0]->hw_ops.stop(
					hw_mgr->devices[dev_type][0]->hw_priv,
					NULL, 0);
				if (rc)
					CAM_ERR(CAM_JPEG, "stop fail %d", rc);
			} else {
				CAM_ERR(CAM_JPEG, "op stop null ");
				rc = -EINVAL;
			}
		}

		hw_mgr->device_in_use[dev_type][0] = false;
		p_cfg_req = hw_mgr->dev_hw_cfg_args[dev_type][0];
		hw_mgr->dev_hw_cfg_args[dev_type][0] = NULL;
	}

	list_for_each_entry_safe(cfg_req, req_temp,
		&hw_mgr->hw_config_req_list, list) {
		if ((struct cam_jpeg_hw_ctx_data *)cfg_req->
			hw_cfg_args.ctxt_to_hw_map != ctx_data)
			continue;

		CAM_INFO(CAM_JPEG, "deleting req %pK", cfg_req);
		list_del_init(&cfg_req->list);
	}

	return rc;
}

static int cam_jpeg_mgr_hw_stop(void *hw_mgr_priv, void *stop_hw_args)
{
	int rc;
	struct cam_hw_stop_args *stop_args =
		(struct cam_hw_stop_args *)stop_hw_args;
	struct cam_jpeg_hw_mgr *hw_mgr = hw_mgr_priv;
	struct cam_jpeg_hw_ctx_data *ctx_data = NULL;

	if (!hw_mgr || !stop_args || !stop_args->ctxt_to_hw_map) {
		CAM_ERR(CAM_JPEG, "Invalid args");
		return -EINVAL;
	}
	mutex_lock(&hw_mgr->hw_mgr_mutex);

	ctx_data = (struct cam_jpeg_hw_ctx_data *)stop_args->ctxt_to_hw_map;
	if (!ctx_data->in_use) {
		CAM_ERR(CAM_JPEG, "ctx is not in use");
		mutex_unlock(&hw_mgr->hw_mgr_mutex);
		return -EINVAL;
	}

	rc = cam_jpeg_mgr_flush(hw_mgr_priv, ctx_data);
	if ((rc))
		CAM_ERR(CAM_JPEG, "flush failed %d", rc);

	mutex_unlock(&hw_mgr->hw_mgr_mutex);

	return rc;
}

static int cam_jpeg_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args)
{
	int rc;
@@ -1184,6 +1281,7 @@ int cam_jpeg_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl)
	hw_mgr_intf->hw_release = cam_jpeg_mgr_release_hw;
	hw_mgr_intf->hw_prepare_update = cam_jpeg_mgr_prepare_hw_update;
	hw_mgr_intf->hw_config = cam_jpeg_mgr_config_hw;
	hw_mgr_intf->hw_stop = cam_jpeg_mgr_hw_stop;

	mutex_init(&g_jpeg_hw_mgr.hw_mgr_mutex);
	spin_lock_init(&g_jpeg_hw_mgr.hw_mgr_lock);
+5 −0
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@
#define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_MASK 0x10000000
#define CAM_JPEG_HW_IRQ_STATUS_RESET_ACK_SHIFT 0x0000000a

#define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK 0x8000000
#define CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_SHIFT 0x0000001b

#define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_MASK 0x00000800
#define CAM_JPEG_HW_IRQ_STATUS_BUS_ERROR_SHIFT 0x0000000b

@@ -63,11 +66,13 @@ static struct cam_jpeg_enc_device_hw_info cam_jpeg_enc_hw_info = {
		.int_mask_enable_all = 0xFFFFFFFF,
		.hw_cmd_start = 0x00000001,
		.reset_cmd = 0x00032093,
		.hw_cmd_stop = 0x00000002,
	},
	.int_status = {
		.framedone = CAM_JPEG_HW_MASK_COMP_FRAMEDONE,
		.resetdone = CAM_JPEG_HW_MASK_COMP_RESET_ACK,
		.iserror = CAM_JPEG_HW_MASK_COMP_ERR,
		.stopdone = CAM_JPEG_HW_IRQ_STATUS_STOP_DONE_MASK,
	}
};

+81 −3
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
	((jpeg_irq_status) & (hi)->int_status.resetdone)
#define CAM_JPEG_HW_IRQ_IS_ERR(jpeg_irq_status, hi) \
	((jpeg_irq_status) & (hi)->int_status.iserror)
#define CAM_JPEG_HW_IRQ_IS_STOP_DONE(jpeg_irq_status, hi) \
	((jpeg_irq_status) & (hi)->int_status.stopdone)

#define CAM_JPEG_ENC_RESET_TIMEOUT msecs_to_jiffies(500)

@@ -181,7 +183,9 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)

	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_enc_dev->hw_lock);
		if (core_info->core_state == CAM_JPEG_ENC_CORE_READY) {
			encoded_size = cam_io_r_mb(mem_base +
				core_info->jpeg_enc_hw_info->reg_offset.
@@ -191,22 +195,42 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
					encoded_size,
					core_info->irq_cb.data);
			} else {
				CAM_ERR(CAM_JPEG, "unexpected done");
				CAM_ERR(CAM_JPEG, "unexpected done, no cb");
			}
		} else {
			CAM_ERR(CAM_JPEG, "unexpected done irq");
		}

		core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
		spin_unlock(&jpeg_enc_dev->hw_lock);
	}
	if (CAM_JPEG_HW_IRQ_IS_RESET_ACK(irq_status, hw_info)) {
		spin_lock(&jpeg_enc_dev->hw_lock);
		if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) {
			core_info->core_state = CAM_JPEG_ENC_CORE_READY;
			complete(&jpeg_enc_dev->hw_complete);
		} else {
			CAM_ERR(CAM_JPEG, "unexpected reset irq");
		}
		spin_unlock(&jpeg_enc_dev->hw_lock);
	}
	if (CAM_JPEG_HW_IRQ_IS_STOP_DONE(irq_status, hw_info)) {
		spin_lock(&jpeg_enc_dev->hw_lock);
		if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) {
			core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
			complete(&jpeg_enc_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_enc_dev->hw_lock);
	}
	/* Unexpected/unintended HW interrupt */
	if (CAM_JPEG_HW_IRQ_IS_ERR(irq_status, hw_info)) {
		spin_lock(&jpeg_enc_dev->hw_lock);
		core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
		CAM_ERR_RATE_LIMIT(CAM_JPEG,
			"error irq_num %d  irq_status = %x , core_state %d",
@@ -217,6 +241,7 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data)
				-1,
				core_info->irq_cb.data);
		}
		spin_unlock(&jpeg_enc_dev->hw_lock);
	}

	return IRQ_HANDLED;
@@ -244,14 +269,18 @@ int cam_jpeg_enc_reset_hw(void *data,
	hw_info = core_info->jpeg_enc_hw_info;
	mem_base = soc_info->reg_map[0].mem_base;

	mutex_lock(&core_info->core_mutex);
	spin_lock(&jpeg_enc_dev->hw_lock);
	if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) {
		CAM_ERR(CAM_JPEG, "alrady resetting");
		spin_unlock(&jpeg_enc_dev->hw_lock);
		mutex_unlock(&core_info->core_mutex);
		return 0;
	}

	reinit_completion(&jpeg_enc_dev->hw_complete);

	core_info->core_state = CAM_JPEG_ENC_CORE_RESETTING;
	spin_unlock(&jpeg_enc_dev->hw_lock);

	cam_io_w_mb(hw_info->reg_val.int_mask_disable_all,
		mem_base + hw_info->reg_offset.int_mask);
@@ -269,6 +298,7 @@ int cam_jpeg_enc_reset_hw(void *data,
		core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
	}

	mutex_unlock(&core_info->core_mutex);
	return 0;
}

@@ -303,6 +333,54 @@ int cam_jpeg_enc_start_hw(void *data,
	return 0;
}

int cam_jpeg_enc_stop_hw(void *data,
	void *stop_args, uint32_t arg_size)
{
	struct cam_hw_info *jpeg_enc_dev = data;
	struct cam_jpeg_enc_device_core_info *core_info = NULL;
	struct cam_hw_soc_info *soc_info = NULL;
	struct cam_jpeg_enc_device_hw_info *hw_info = NULL;
	void __iomem *mem_base;
	unsigned long rem_jiffies;

	if (!jpeg_enc_dev) {
		CAM_ERR(CAM_JPEG, "Invalid args");
		return -EINVAL;
	}
	soc_info = &jpeg_enc_dev->soc_info;
	core_info =
		(struct cam_jpeg_enc_device_core_info *)jpeg_enc_dev->
		core_info;
	hw_info = core_info->jpeg_enc_hw_info;
	mem_base = soc_info->reg_map[0].mem_base;

	mutex_unlock(&core_info->core_mutex);
	spin_lock(&jpeg_enc_dev->hw_lock);
	if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) {
		CAM_ERR(CAM_JPEG, "alrady stopping");
		spin_unlock(&jpeg_enc_dev->hw_lock);
		mutex_unlock(&core_info->core_mutex);
		return 0;
	}

	reinit_completion(&jpeg_enc_dev->hw_complete);
	core_info->core_state = CAM_JPEG_ENC_CORE_ABORTING;
	spin_unlock(&jpeg_enc_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_enc_dev->hw_complete,
		CAM_JPEG_ENC_RESET_TIMEOUT);
	if (!rem_jiffies) {
		CAM_ERR(CAM_JPEG, "error Reset Timeout");
		core_info->core_state = CAM_JPEG_ENC_CORE_NOT_READY;
	}

	mutex_unlock(&core_info->core_mutex);
	return 0;
}

int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
	void *cmd_args, uint32_t arg_size)
{
+5 −0
Original line number Diff line number Diff line
@@ -37,12 +37,14 @@ struct cam_jpeg_enc_regval {
	uint32_t int_mask_enable_all;
	uint32_t hw_cmd_start;
	uint32_t reset_cmd;
	uint32_t hw_cmd_stop;
};

struct cam_jpeg_enc_int_status {
	uint32_t framedone;
	uint32_t resetdone;
	uint32_t iserror;
	uint32_t stopdone;
};

struct cam_jpeg_enc_device_hw_info {
@@ -55,6 +57,7 @@ enum cam_jpeg_enc_core_state {
	CAM_JPEG_ENC_CORE_NOT_READY,
	CAM_JPEG_ENC_CORE_READY,
	CAM_JPEG_ENC_CORE_RESETTING,
	CAM_JPEG_ENC_CORE_ABORTING,
	CAM_JPEG_ENC_CORE_STATE_MAX,
};

@@ -73,6 +76,8 @@ int cam_jpeg_enc_deinit_hw(void *device_priv,
	void *init_hw_args, uint32_t arg_size);
int cam_jpeg_enc_start_hw(void *device_priv,
	void *start_hw_args, uint32_t arg_size);
int cam_jpeg_enc_stop_hw(void *device_priv,
	void *stop_hw_args, uint32_t arg_size);
int cam_jpeg_enc_reset_hw(void *device_priv,
	void *reset_hw_args, uint32_t arg_size);
int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type,
Loading