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

Commit 9703cf92 authored by Anil Kumar Kanakanti's avatar Anil Kumar Kanakanti
Browse files

msm: camera: cci: Add CCI Global reset during CCI HW init



During first CCI HW initialization, CCI HW global reset has to be called.
Removed is_initialized removed, as it can be controlled through
master_active_slave ref count to verify there is any active slave or not.

CRs-Fixed: 2782553
Change-Id: Id845bfc936b976e160231ed3a0acbc951c32ad7f
Signed-off-by: default avatarAnil Kumar Kanakanti <akanakan@codeaurora.org>
parent 73300515
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1171,7 +1171,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
					CCI_I2C_M0_READ_BUF_LEVEL_ADDR +
					master * 0x100);
				CAM_ERR(CAM_CCI,
					"wait timeout for RD_DONE irq for cci: %d, master: %d, rc = %d FIFO buf_lvl:0x%x, rc: %d",
					"wait timeout for RD_DONE irq for cci: %d, master: %d, FIFO buf_lvl:0x%x, rc: %d",
					cci_dev->soc_info.index, master,
					val, rc);
				cam_cci_dump_registers(cci_dev,
+0 −1
Original line number Diff line number Diff line
@@ -144,7 +144,6 @@ struct cam_cci_master_info {
	struct semaphore master_sem;
	bool is_first_req;
	uint16_t freq_ref_cnt;
	bool is_initilized;
};

struct cam_cci_clk_params_t {
+102 −101
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
	void __iomem *base = NULL;
	struct cam_hw_soc_info *soc_info = NULL;
	uint32_t max_queue_0_size = 0, max_queue_1_size = 0;
	struct cam_cci_master_info *cci_master;

	soc_info = &cci_dev->soc_info;
	base = soc_info->reg_map[0].mem_base;
@@ -25,34 +26,28 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
		max_queue_1_size = CCI_I2C_QUEUE_1_SIZE;
	}

	cci_dev->master_active_slave[master]++;
	if (!cci_dev->cci_master_info[master].is_initilized) {
	cci_master = &cci_dev->cci_master_info[master];
	/* Re-initialize the completion */
		reinit_completion(
		&cci_dev->cci_master_info[master].reset_complete);
		reinit_completion(&cci_dev->cci_master_info[master].rd_done);
	reinit_completion(&cci_master->reset_complete);
	reinit_completion(&cci_master->rd_done);

	/* reinit the reports for the queue */
	for (i = 0; i < NUM_QUEUES; i++)
			reinit_completion(
			&cci_dev->cci_master_info[master].report_q[i]);
		reinit_completion(&cci_master->report_q[i]);

	/* Set reset pending flag to true */
		cci_dev->cci_master_info[master].reset_pending = true;
	cci_master->reset_pending = true;
	cam_io_w_mb((master == MASTER_0) ?
		CCI_M0_RESET_RMSK : CCI_M1_RESET_RMSK,
		base + CCI_RESET_CMD_ADDR);
	if (!wait_for_completion_timeout(
			&cci_dev->cci_master_info[master].reset_complete,
			CCI_TIMEOUT)) {
		&cci_master->reset_complete, CCI_TIMEOUT)) {
		CAM_ERR(CAM_CCI,
			"Failed: reset complete timeout for master: %d",
			master);
		rc = -ETIMEDOUT;
			cci_dev->master_active_slave[master]--;
		return rc;
	}

	flush_workqueue(cci_dev->write_wq[master]);

	/* Setting up the queue size for master */
@@ -62,14 +57,10 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
				= max_queue_1_size;

	CAM_DBG(CAM_CCI, "CCI Master[%d] :: Q0: %d Q1: %d", master,
			cci_dev->cci_i2c_queue_info[master][QUEUE_0]
				.max_queue_size,
			cci_dev->cci_i2c_queue_info[master][QUEUE_1]
				.max_queue_size);
		cci_dev->cci_i2c_queue_info[master][QUEUE_0].max_queue_size,
		cci_dev->cci_i2c_queue_info[master][QUEUE_1].max_queue_size);

	cci_dev->cci_master_info[master].status = 0;
		cci_dev->cci_master_info[master].is_initilized = true;
	}

	return 0;
}
@@ -117,18 +108,7 @@ int cam_cci_init(struct v4l2_subdev *sd,
		return rc;
	}

	if (cci_dev->ref_count++) {
		rc = cam_cci_init_master(cci_dev, master);
		if (rc) {
			CAM_ERR(CAM_CCI, "Failed to init: Master: %d: rc: %d",
				master, rc);
			cci_dev->ref_count--;
		}
		CAM_DBG(CAM_CCI, "ref_count %d, master: %d",
			cci_dev->ref_count, master);
		return rc;
	}

	if (!cci_dev->ref_count) {
		ahb_vote.type = CAM_VOTE_ABSOLUTE;
		ahb_vote.vote.level = CAM_LOWSVS_VOTE;
		axi_vote.num_paths = 1;
@@ -150,8 +130,8 @@ int cam_cci_init(struct v4l2_subdev *sd,
		rc = cam_soc_util_enable_platform_resource(soc_info, true,
			CAM_LOWSVS_VOTE, true);
		if (rc < 0) {
		CAM_DBG(CAM_CCI, "request platform resources failed, rc: %d",
			rc);
			CAM_DBG(CAM_CCI,
				"request platform resources failed,rc:%d", rc);
			goto platform_enable_failed;
		}

@@ -161,16 +141,26 @@ int cam_cci_init(struct v4l2_subdev *sd,
		cci_dev->payload_size = MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11;
		cci_dev->support_seq_write = 1;

	rc = cam_cci_init_master(cci_dev, master);
	if (rc) {
		CAM_ERR(CAM_CCI, "Failed to init: Master: %d, rc: %d",
			master, rc);
		goto reset_complete_failed;
	}

		for (i = 0; i < MASTER_MAX; i++)
			cci_dev->i2c_freq_mode[i] = I2C_MAX_MODES;

		reinit_completion(
			&cci_dev->cci_master_info[master].reset_complete);
		cci_dev->cci_master_info[master].reset_pending = true;
		cci_dev->cci_master_info[master].status = 0;

		cam_io_w_mb(CCI_RESET_CMD_RMSK, base + CCI_RESET_CMD_ADDR);

		if (!wait_for_completion_timeout(
			&cci_dev->cci_master_info[master].reset_complete,
			CCI_TIMEOUT)) {
			CAM_ERR(CAM_CCI,
				"Failed: reset complete timeout for master: %d",
				master);
			rc = -ETIMEDOUT;
			goto platform_enable_failed;
		}

		cam_io_w_mb(CCI_IRQ_MASK_0_RMSK, base + CCI_IRQ_MASK_0_ADDR);
		cam_io_w_mb(CCI_IRQ_MASK_0_RMSK, base + CCI_IRQ_CLEAR_0_ADDR);
		cam_io_w_mb(CCI_IRQ_MASK_1_RMSK, base + CCI_IRQ_MASK_1_ADDR);
@@ -184,15 +174,28 @@ int cam_cci_init(struct v4l2_subdev *sd,
			cam_io_w_mb(CCI_I2C_RD_THRESHOLD_VALUE,
					base + CCI_I2C_M1_RD_THRESHOLD_ADDR);
		}

		cci_dev->cci_state = CCI_STATE_ENABLED;
	}
	cci_dev->ref_count++;

	if (!cci_dev->master_active_slave[master]) {
		rc = cam_cci_init_master(cci_dev, master);
		if (rc) {
			CAM_ERR(CAM_CCI, "Failed to init: Master: %d: rc: %d",
				master, rc);
			goto reset_complete_failed;
		}
		CAM_DBG(CAM_CCI, "ref_count %d, master: %d",
			cci_dev->ref_count, master);
	}
	cci_dev->master_active_slave[master]++;

	return 0;

reset_complete_failed:
	cam_soc_util_disable_platform_resource(soc_info, 1, 1);
platform_enable_failed:
	cci_dev->ref_count--;
platform_enable_failed:
	cam_cpas_stop(cci_dev->cpas_handle);

	return rc;
@@ -213,7 +216,6 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev)
	for (i = 0; i < MASTER_MAX; i++) {
		new_cci_dev->cci_master_info[i].status = 0;
		new_cci_dev->cci_master_info[i].is_first_req = true;
		new_cci_dev->cci_master_info[i].is_initilized = false;
		mutex_init(&new_cci_dev->cci_master_info[i].mutex);
		sema_init(&new_cci_dev->cci_master_info[i].master_sem, 1);
		spin_lock_init(&new_cci_dev->cci_master_info[i].freq_cnt);
@@ -404,7 +406,6 @@ int cam_cci_soc_release(struct cci_device *cci_dev,
	}

	if (!(--cci_dev->master_active_slave[master])) {
		cci_dev->cci_master_info[master].is_initilized = false;
		CAM_DBG(CAM_CCI,
			"All submodules are released for master: %d", master);
	}