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

Commit ae401df5 authored by Tony Lijo Jose's avatar Tony Lijo Jose
Browse files

msm: camera: cci: Handle burst read for cci hw 1.2



CCI hw 1.2 does not support burst read due to the absence of READ
THRESHOLD irq. Due to this we need to handle the cci burst read as a
sequence of reads (each read is of chunk size 0xE).

CRs-Fixed: 2585335
Change-Id: Icbc327475e6dd8838b1d665f71d62dc6efebb7d7
Signed-off-by: default avatarTony Lijo Jose <tjose@codeaurora.org>
parent 2cf3747f
Loading
Loading
Loading
Loading
+80 −1
Original line number Diff line number Diff line
@@ -1498,6 +1498,76 @@ static int32_t cam_cci_i2c_write_async(struct v4l2_subdev *sd,
	return rc;
}

static int32_t cam_cci_read_bytes_v_1_2(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl)
{
	int32_t rc = 0;
	struct cci_device *cci_dev = NULL;
	enum cci_i2c_master_t master;
	struct cam_cci_read_cfg *read_cfg = NULL;
	uint16_t read_bytes = 0;

	if (!sd || !c_ctrl) {
		CAM_ERR(CAM_CCI, "sd %pK c_ctrl %pK", sd, c_ctrl);
		return -EINVAL;
	}
	if (!c_ctrl->cci_info) {
		CAM_ERR(CAM_CCI, "cci_info NULL");
		return -EINVAL;
	}
	cci_dev = v4l2_get_subdevdata(sd);
	if (!cci_dev) {
		CAM_ERR(CAM_CCI, "cci_dev NULL");
		return -EINVAL;
	}
	if (cci_dev->cci_state != CCI_STATE_ENABLED) {
		CAM_ERR(CAM_CCI, "invalid cci state %d", cci_dev->cci_state);
		return -EINVAL;
	}

	if (c_ctrl->cci_info->cci_i2c_master >= MASTER_MAX
			|| c_ctrl->cci_info->cci_i2c_master < 0) {
		CAM_ERR(CAM_CCI, "Invalid I2C master addr");
		return -EINVAL;
	}

	master = c_ctrl->cci_info->cci_i2c_master;
	read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
	if ((!read_cfg->num_byte) || (read_cfg->num_byte > CCI_I2C_MAX_READ)) {
		CAM_ERR(CAM_CCI, "read num bytes 0");
		rc = -EINVAL;
		goto ERROR;
	}

	read_bytes = read_cfg->num_byte;
	CAM_DBG(CAM_CCI, "Bytes to read %u", read_bytes);
	do {
		if (read_bytes >= CCI_READ_MAX_V_1_2)
			read_cfg->num_byte = CCI_READ_MAX_V_1_2;
		else
			read_cfg->num_byte = read_bytes;

		cci_dev->is_burst_read = false;
		rc = cam_cci_read(sd, c_ctrl);
		if (rc) {
			CAM_ERR(CAM_CCI, "failed to read rc:%d", rc);
			goto ERROR;
		}

		if (read_bytes >= CCI_READ_MAX_V_1_2) {
			read_cfg->addr += CCI_READ_MAX_V_1_2;
			read_cfg->data += CCI_READ_MAX_V_1_2;
			read_bytes -= CCI_READ_MAX_V_1_2;
		} else {
			read_bytes = 0;
		}
	} while (read_bytes);

ERROR:
	cci_dev->is_burst_read = false;
	return rc;
}

static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl)
{
@@ -1701,7 +1771,16 @@ int32_t cam_cci_core_cfg(struct v4l2_subdev *sd,
		mutex_unlock(&cci_dev->init_mutex);
		break;
	case MSM_CCI_I2C_READ:
		/*
		 * CCI version 1.2 does not support burst read
		 * due to the absence of the read threshold register
		 */
		if (cci_dev->hw_version == CCI_VERSION_1_2_9) {
			CAM_DBG(CAM_CCI, "cci-v1.2 no burst read");
			rc = cam_cci_read_bytes_v_1_2(sd, cci_ctrl);
		} else {
			rc = cam_cci_read_bytes(sd, cci_ctrl);
		}
		break;
	case MSM_CCI_I2C_WRITE:
	case MSM_CCI_I2C_WRITE_SEQ:
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@

/* Max bytes that can be read per CCI read transaction */
#define CCI_READ_MAX 256
#define CCI_READ_MAX_V_1_2 0xE
#define CCI_I2C_READ_MAX_RETRIES 3
#define CCI_I2C_MAX_READ 8192
#define CCI_I2C_MAX_WRITE 8192
@@ -72,6 +73,7 @@
#define PRIORITY_QUEUE (QUEUE_0)
#define SYNC_QUEUE (QUEUE_1)

#define CCI_VERSION_1_2_9 0x10020009
enum cci_i2c_sync {
	MSM_SYNC_DISABLE,
	MSM_SYNC_ENABLE,
+7 −6
Original line number Diff line number Diff line
@@ -117,8 +117,7 @@ int cam_cci_init(struct v4l2_subdev *sd,
		MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11;
	cci_dev->support_seq_write = 1;

	if (of_device_is_compatible(soc_info->dev->of_node,
						"qcom,cci-v1.2")) {
	if (cci_dev->hw_version == CCI_VERSION_1_2_9) {
		max_queue_0_size = CCI_I2C_QUEUE_0_SIZE_V_1_2;
		max_queue_1_size = CCI_I2C_QUEUE_1_SIZE_V_1_2;
	} else {
@@ -177,10 +176,12 @@ int cam_cci_init(struct v4l2_subdev *sd,
	}

	/* Set RD FIFO threshold for M0 & M1 */
	if (cci_dev->hw_version != CCI_VERSION_1_2_9) {
		cam_io_w_mb(CCI_I2C_RD_THRESHOLD_VALUE,
				base + CCI_I2C_M0_RD_THRESHOLD_ADDR);
		cam_io_w_mb(CCI_I2C_RD_THRESHOLD_VALUE,
				base + CCI_I2C_M1_RD_THRESHOLD_ADDR);
	}

	cci_dev->cci_state = CCI_STATE_ENABLED;