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

Commit aac867de authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera2: cpp: Enhance timeout handler for multi-frame processing"

parents 08c3d4e6 e0100bc1
Loading
Loading
Loading
Loading
+66 −51
Original line number Diff line number Diff line
@@ -305,7 +305,8 @@ static int get_clock_index(const char *clk_name)
}


static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev);
static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
	uint8_t put_buf, uint8_t modify_timer);
static void cpp_load_fw(struct cpp_device *cpp_dev, char *fw_name_bin);
static void cpp_timer_callback(unsigned long data);

@@ -818,13 +819,15 @@ void msm_cpp_do_tasklet(unsigned long data)
					/* delete CPP timer */
					CPP_DBG("delete timer.\n");
					msm_cpp_timer_queue_update(cpp_dev);
					msm_cpp_notify_frame_done(cpp_dev);
					msm_cpp_notify_frame_done(cpp_dev,
						0, 1);
				} else if (msg_id ==
					MSM_CPP_MSG_ID_FRAME_NACK) {
					pr_err("NACK error from hw!!\n");
					CPP_DBG("delete timer.\n");
					msm_cpp_timer_queue_update(cpp_dev);
					msm_cpp_notify_frame_done(cpp_dev);
					msm_cpp_notify_frame_done(cpp_dev,
						0, 1);
				}
				i += cmd_len + 2;
			}
@@ -1433,7 +1436,8 @@ static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev,
	return rc;
}

static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
	uint8_t put_buf, uint8_t modify_timer)
{
	struct v4l2_event v4l2_evt;
	struct msm_queue_cmd *frame_qcmd = NULL;
@@ -1476,6 +1480,15 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
			buff_mgr_info.reserved = processed_frame->reserved;
			buff_mgr_info.index =
				processed_frame->output_buffer_info[0].index;
			if (put_buf) {
				rc = msm_cpp_buffer_ops(cpp_dev,
					VIDIOC_MSM_BUF_MNGR_PUT_BUF,
					&buff_mgr_info);
				if (rc < 0) {
					pr_err("error putting buffer\n");
					rc = -EINVAL;
				}
			} else {
				rc = msm_cpp_buffer_ops(cpp_dev,
					VIDIOC_MSM_BUF_MNGR_BUF_DONE,
					&buff_mgr_info);
@@ -1484,6 +1497,7 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
					rc = -EINVAL;
				}
			}
		}

		if (processed_frame->duplicate_output  &&
			!processed_frame->
@@ -1499,6 +1513,15 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
			buff_mgr_info.timestamp = processed_frame->timestamp;
			buff_mgr_info.index =
				processed_frame->output_buffer_info[1].index;
			if (put_buf) {
				rc = msm_cpp_buffer_ops(cpp_dev,
					VIDIOC_MSM_BUF_MNGR_PUT_BUF,
					&buff_mgr_info);
				if (rc < 0) {
					pr_err("error putting buffer\n");
					rc = -EINVAL;
				}
			} else {
				rc = msm_cpp_buffer_ops(cpp_dev,
					VIDIOC_MSM_BUF_MNGR_BUF_DONE,
					&buff_mgr_info);
@@ -1507,12 +1530,13 @@ static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
					rc = -EINVAL;
				}
			}
		}
NOTIFY_FRAME_DONE:
		v4l2_evt.id = processed_frame->inst_id;
		v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
		v4l2_event_queue(cpp_dev->msm_sd.sd.devnode, &v4l2_evt);

		if (queue->len > 0) {
		if (modify_timer && (queue->len > 0)) {
			rc = mod_timer(&cpp_timer.cpp_timer,
				jiffies + msecs_to_jiffies(CPP_CMD_TIMEOUT_MS));
			if (rc < 0)
@@ -1557,11 +1581,11 @@ static int msm_cpp_dump_frame_cmd(struct msm_cpp_frame_info_t *frame_info)

static void msm_cpp_do_timeout_work(struct work_struct *work)
{
	int ret;
	uint32_t i = 0, j = 0;
	struct msm_cpp_frame_info_t *this_frame = NULL;
	uint32_t i = 0;
	int32_t queue_len = 0;
	struct msm_device_queue *queue = NULL;

	pr_err("cpp_timer_callback called. (jiffies=%lu)\n",
	pr_info("cpp_timer_callback called. (jiffies=%lu)\n",
		jiffies);
	if (!work || cpp_timer.data.cpp_dev->state != CPP_STATE_ACTIVE) {
		pr_err("Invalid work:%p or state:%d\n", work,
@@ -1569,15 +1593,15 @@ static void msm_cpp_do_timeout_work(struct work_struct *work)
		return;
	}
	if (!atomic_read(&cpp_timer.used)) {
		pr_err("Delayed trigger, IRQ serviced\n");
		pr_info("Delayed trigger, IRQ serviced\n");
		return;
	}

	disable_irq(cpp_timer.data.cpp_dev->irq->start);
	pr_err("Reloading firmware\n");
	pr_info("Reloading firmware\n");
	cpp_load_fw(cpp_timer.data.cpp_dev,
		cpp_timer.data.cpp_dev->fw_name_bin);
	pr_err("Firmware loading done\n");
	pr_info("Firmware loading done\n");
	enable_irq(cpp_timer.data.cpp_dev->irq->start);
	msm_camera_io_w_mb(0x8, cpp_timer.data.cpp_dev->base +
		MSM_CPP_MICRO_IRQGEN_MASK);
@@ -1586,39 +1610,27 @@ static void msm_cpp_do_timeout_work(struct work_struct *work)
		MSM_CPP_MICRO_IRQGEN_CLR);

	if (!atomic_read(&cpp_timer.used)) {
		pr_err("Delayed trigger, IRQ serviced\n");
		pr_info("Delayed trigger, IRQ serviced\n");
		return;
	}

	if (cpp_timer.data.cpp_dev->timeout_trial_cnt >=
		MSM_CPP_MAX_TIMEOUT_TRIAL) {
		pr_info("Max trial reached\n");
		msm_cpp_notify_frame_done(cpp_timer.data.cpp_dev);
		cpp_timer.data.cpp_dev->timeout_trial_cnt = 0;
		return;
	}
	queue = &cpp_timer.data.cpp_dev->processing_q;
	queue_len = queue->len;
	mutex_lock(&cpp_timer.data.cpp_dev->mutex);
	for (i = 0; i < MAX_CPP_PROCESSING_FRAME; i++)
		msm_cpp_dump_frame_cmd(cpp_timer.data.processed_frame[i]);

	for (j = 0; j < MAX_CPP_PROCESSING_FRAME; j++)
		msm_cpp_dump_frame_cmd(cpp_timer.data.processed_frame[j]);
	while (queue_len) {
		msm_cpp_notify_frame_done(cpp_timer.data.cpp_dev, 1, 0);
		queue_len--;
	}
	atomic_set(&cpp_timer.used, 0);
	for (i = 0; i < MAX_CPP_PROCESSING_FRAME; i++)
		cpp_timer.data.processed_frame[i] = NULL;
	cpp_timer.data.cpp_dev->timeout_trial_cnt = 0;
	mutex_unlock(&cpp_timer.data.cpp_dev->mutex);

	CPP_DBG("Starting timer to fire in %d ms. (jiffies=%lu)\n",
		CPP_CMD_TIMEOUT_MS, jiffies);
	ret = mod_timer(&cpp_timer.cpp_timer,
		jiffies + msecs_to_jiffies(CPP_CMD_TIMEOUT_MS));
	if (ret)
		CPP_DBG("Timer has not expired yet\n");
	for (j = 0; j < MAX_CPP_PROCESSING_FRAME; j++) {
		this_frame = cpp_timer.data.processed_frame[j];
		if (this_frame) {
			pr_err("Rescheduling for identity=0x%x, frame_id=%03d\n",
				this_frame->identity, this_frame->frame_id);
			msm_cpp_write(0x6, cpp_timer.data.cpp_dev->base);
			for (i = 0; i < this_frame->msg_len; i++)
				msm_cpp_write(this_frame->cpp_cmd_msg[i],
					cpp_timer.data.cpp_dev->base);
		}
	}
	cpp_timer.data.cpp_dev->timeout_trial_cnt++;
	pr_info("exit\n");
	return;
}

@@ -2976,9 +2988,11 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
		struct msm_cpp_frame_info32_t k32_process_frame;

		CPP_DBG("VIDIOC_MSM_CPP_GET_EVENTPAYLOAD\n");
		mutex_lock(&cpp_dev->mutex);
		event_qcmd = msm_dequeue(queue, list_eventdata);
		if (!event_qcmd) {
			pr_err("no queue cmd available");
			mutex_unlock(&cpp_dev->mutex);
			return -EINVAL;
		}
		process_frame = event_qcmd->command;
@@ -2997,6 +3011,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
		kfree(process_frame);
		kfree(event_qcmd);
		cmd = VIDIOC_MSM_CPP_GET_EVENTPAYLOAD;
		mutex_unlock(&cpp_dev->mutex);
		break;
	}
	case VIDIOC_MSM_CPP_SET_CLOCK32:
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@
#define MSM_CPP_START_ADDRESS		0x0
#define MSM_CPP_END_ADDRESS			0x3F00

#define MSM_CPP_POLL_RETRIES		20
#define MSM_CPP_POLL_RETRIES		200
#define MSM_CPP_TASKLETQ_SIZE		16
#define MSM_CPP_TX_FIFO_LEVEL		16
#define MSM_CPP_RX_FIFO_LEVEL		512