Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +8 −1 Original line number Diff line number Diff line Loading @@ -2378,7 +2378,9 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; ctx_isp->substate_activated = ctx_isp->rdi_only_context ? CAM_ISP_CTX_ACTIVATED_APPLIED : CAM_ISP_CTX_ACTIVATED_SOF; CAM_ISP_CTX_ACTIVATED_APPLIED : (req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH : CAM_ISP_CTX_ACTIVATED_SOF; /* * Only place to change state before calling the hw due to Loading @@ -2396,6 +2398,11 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, goto end; } CAM_DBG(CAM_ISP, "start device success"); if (req_isp->num_fence_map_out) { list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); } end: return rc; } Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +195 −12 Original line number Diff line number Diff line Loading @@ -205,8 +205,6 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev, CAM_INFO(CAM_CCI, "****CCI MASTER %d Registers ****", master); for (i = 0; i < DEBUG_MASTER_REG_COUNT; i++) { if (i == 6) continue; reg_offset = DEBUG_MASTER_REG_START + master*0x100 + i * 4; read_val = cam_io_r_mb(base + reg_offset); CAM_INFO(CAM_CCI, "offset = 0x%X value = 0x%X", Loading Loading @@ -867,6 +865,180 @@ static int32_t cam_cci_data_queue(struct cci_device *cci_dev, return rc; } static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, struct cam_cci_ctrl *c_ctrl) { int32_t rc = 0; uint32_t val = 0, i = 0; unsigned long rem_jiffies; int32_t read_words = 0, exp_words = 0; int32_t index = 0, first_byte = 0, total_read_words = 0; enum cci_i2c_master_t master; enum cci_i2c_queue_t queue = QUEUE_1; struct cci_device *cci_dev = NULL; struct cam_cci_read_cfg *read_cfg = NULL; struct cam_hw_soc_info *soc_info = NULL; void __iomem *base = NULL; cci_dev = v4l2_get_subdevdata(sd); master = c_ctrl->cci_info->cci_i2c_master; read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg; 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; } soc_info = &cci_dev->soc_info; base = soc_info->reg_map[0].mem_base; mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]); /* * Todo: If there is a change in frequency of operation * Wait for previos transaction to complete */ /* Set the I2C Frequency */ rc = cam_cci_set_clk_param(cci_dev, c_ctrl); if (rc < 0) { CAM_ERR(CAM_CCI, "cam_cci_set_clk_param failed rc = %d", rc); goto rel_mutex; } /* * Call validate queue to make sure queue is empty before starting. * If this call fails, don't proceed with i2c_read call. This is to * avoid overflow / underflow of queue */ rc = cam_cci_validate_queue(cci_dev, cci_dev->cci_i2c_queue_info[master][queue].max_queue_size - 1, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc); goto rel_mutex; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { CAM_ERR(CAM_CCI, "More than max retries"); goto rel_mutex; } if (read_cfg->data == NULL) { CAM_ERR(CAM_CCI, "Data ptr is NULL"); goto rel_mutex; } if (read_cfg->addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX) { CAM_ERR(CAM_CCI, "failed : Invalid addr type: %u", read_cfg->addr_type); rc = -EINVAL; goto rel_mutex; } CAM_DBG(CAM_CCI, "set param sid 0x%x retries %d id_map %d", c_ctrl->cci_info->sid, c_ctrl->cci_info->retries, c_ctrl->cci_info->id_map); val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 | c_ctrl->cci_info->retries << 16 | c_ctrl->cci_info->id_map << 18; rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = CCI_I2C_LOCK_CMD; rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4); for (i = 0; i < read_cfg->addr_type; i++) { val |= ((read_cfg->addr >> (i << 3)) & 0xFF) << ((read_cfg->addr_type - i) << 3); } rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = CCI_I2C_READ_CMD | (read_cfg->num_byte << 4); rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = CCI_I2C_UNLOCK_CMD; rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + master * 0x200 + queue * 0x100); CAM_DBG(CAM_CCI, "cur word cnt 0x%x", val); cam_io_w_mb(val, base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + master * 0x200 + queue * 0x100); val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); exp_words = ((read_cfg->num_byte / 4) + 1); while (exp_words != total_read_words) { rem_jiffies = wait_for_completion_timeout( &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); if (!rem_jiffies) { rc = -ETIMEDOUT; val = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); CAM_ERR(CAM_CCI, "wait_for_completion_timeout rc = %d FIFO buf_lvl:0x%x", rc, val); #ifdef DUMP_CCI_REGISTERS cam_cci_dump_registers(cci_dev, master, queue); #endif cam_cci_flush_queue(cci_dev, master); goto rel_mutex; } read_words = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); total_read_words += read_words; do { val = cam_io_r_mb(base + CCI_I2C_M0_READ_DATA_ADDR + master * 0x100); for (i = 0; (i < 4) && (index < read_cfg->num_byte); i++) { CAM_DBG(CAM_CCI, "i:%d index:%d", i, index); if (!first_byte) { CAM_DBG(CAM_CCI, "sid 0x%x", val & 0xFF); first_byte++; } else { read_cfg->data[index] = (val >> (i * 8)) & 0xFF; CAM_DBG(CAM_CCI, "data[%d] 0x%x", index, read_cfg->data[index]); index++; } } } while (--read_words > 0); } rel_mutex: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); return rc; } static int32_t cam_cci_read(struct v4l2_subdev *sd, struct cam_cci_ctrl *c_ctrl) { Loading Loading @@ -1003,7 +1175,11 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, #endif if (rc == 0) rc = -ETIMEDOUT; CAM_ERR(CAM_CCI, "wait_for_completion_timeout rc = %d", rc); val = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); CAM_ERR(CAM_CCI, "wait_for_completion_timeout rc = %d FIFO buf_lvl: 0x%x", rc, val); cam_cci_flush_queue(cci_dev, master); goto rel_mutex; } else { Loading Loading @@ -1223,19 +1399,26 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd, read_bytes = read_cfg->num_byte; do { if (read_bytes > CCI_READ_MAX) read_cfg->num_byte = CCI_READ_MAX; if (read_bytes > CCI_I2C_MAX_BYTE_COUNT) read_cfg->num_byte = CCI_I2C_MAX_BYTE_COUNT; else read_cfg->num_byte = read_bytes; if (read_cfg->num_byte > CCI_READ_MAX) rc = cam_cci_burst_read(sd, c_ctrl); else rc = cam_cci_read(sd, c_ctrl); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc %d", rc); if (!rc) { CAM_ERR(CAM_CCI, "failed to read rc:%d", rc); goto ERROR; } if (read_bytes > CCI_READ_MAX) { read_cfg->addr += CCI_READ_MAX; read_cfg->data += CCI_READ_MAX; read_bytes -= CCI_READ_MAX; if (read_bytes > CCI_I2C_MAX_BYTE_COUNT) { read_cfg->addr += (CCI_I2C_MAX_BYTE_COUNT / read_cfg->data_type); read_cfg->data += CCI_I2C_MAX_BYTE_COUNT; read_bytes -= CCI_I2C_MAX_BYTE_COUNT; } else { read_bytes = 0; } Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +46 −16 Original line number Diff line number Diff line Loading @@ -60,18 +60,23 @@ static long cam_cci_subdev_compat_ioctl(struct v4l2_subdev *sd, irqreturn_t cam_cci_irq(int irq_num, void *data) { uint32_t irq; uint32_t irq_status0 = 0; uint32_t irq_status1 = 0; struct cci_device *cci_dev = data; struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; bool burst_read_assert = false; irq = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); cam_io_w_mb(irq, base + CCI_IRQ_CLEAR_0_ADDR); irq_status0 = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); irq_status1 = cam_io_r_mb(base + CCI_IRQ_STATUS_1_ADDR); cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR); cam_io_w_mb(irq_status1, base + CCI_IRQ_CLEAR_1_ADDR); cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); if (irq & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) { CAM_DBG(CAM_CCI, "irq0:%x irq1:%x", irq_status0, irq_status1); if (irq_status0 & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) { if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) { cci_dev->cci_master_info[MASTER_0].reset_pending = FALSE; Loading @@ -85,11 +90,24 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].reset_complete); } } if (irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) { if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) && (irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD)) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); burst_read_assert = true; } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) && (!burst_read_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) && (!burst_read_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; Loading @@ -106,7 +124,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_0].lock_q[QUEUE_0], flags); } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; Loading @@ -123,11 +141,23 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_0].lock_q[QUEUE_1], flags); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) { if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) && (irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD)) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); burst_read_assert = true; } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) && (!burst_read_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) && (!burst_read_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; Loading @@ -144,7 +174,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].lock_q[QUEUE_0], flags); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; Loading @@ -161,27 +191,27 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].lock_q[QUEUE_1], flags); } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; cam_io_w_mb(CCI_M0_RESET_RMSK, base + CCI_RESET_CMD_ADDR); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_1].reset_pending = TRUE; cam_io_w_mb(CCI_M1_RESET_RMSK, base + CCI_RESET_CMD_ADDR); } if (irq & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) { cci_dev->cci_master_info[MASTER_0].status = -EINVAL; cam_io_w_mb(CCI_M0_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR); CAM_DBG(CAM_CCI, "MASTER_0 error 0x%x", irq); CAM_DBG(CAM_CCI, "MASTER_0 error 0x%x", irq_status0); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) { cci_dev->cci_master_info[MASTER_1].status = -EINVAL; cam_io_w_mb(CCI_M1_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR); CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq); CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0); } return IRQ_HANDLED; } Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +3 −7 Original line number Diff line number Diff line Loading @@ -65,19 +65,14 @@ #define MAX_LRME_V4l2_EVENTS 30 /* Max bytes that can be read per CCI read transaction */ #define CCI_READ_MAX 12 #define CCI_READ_MAX 256 #define CCI_I2C_READ_MAX_RETRIES 3 #define CCI_I2C_MAX_READ 8192 #define CCI_I2C_MAX_WRITE 8192 #define CCI_I2C_MAX_BYTE_COUNT 65535 #define CAMX_CCI_DEV_NAME "cam-cci-driver" /* Max bytes that can be read per CCI read transaction */ #define CCI_READ_MAX 12 #define CCI_I2C_READ_MAX_RETRIES 3 #define CCI_I2C_MAX_READ 8192 #define CCI_I2C_MAX_WRITE 8192 #define MAX_CCI 2 #define PRIORITY_QUEUE (QUEUE_0) Loading Loading @@ -127,6 +122,7 @@ struct cam_cci_read_cfg { uint16_t addr_type; uint8_t *data; uint16_t num_byte; uint16_t data_type; }; struct cam_cci_i2c_queue_info { Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h +11 −2 Original line number Diff line number Diff line Loading @@ -43,27 +43,36 @@ #define CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x00000310 #define CCI_IRQ_MASK_0_ADDR 0x00000c04 #define CCI_IRQ_MASK_0_RMSK 0x7fff7ff7 #define CCI_IRQ_MASK_1_ADDR 0x00000c10 #define CCI_IRQ_MASK_1_RMSK 0x00110000 #define CCI_IRQ_CLEAR_0_ADDR 0x00000c08 #define CCI_IRQ_CLEAR_1_ADDR 0x00000c14 #define CCI_IRQ_STATUS_0_ADDR 0x00000c0c #define CCI_IRQ_STATUS_1_ADDR 0x00000c18 #define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK 0x4000000 #define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK 0x2000000 #define CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK 0x1000000 #define CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK 0x100000 #define CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK 0x10000 #define CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK 0x1000 #define CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD 0x100000 #define CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK 0x100 #define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK 0x10 #define CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK 0x18000EE6 #define CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK 0x60EE6000 #define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK 0x1 #define CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD 0x10000 #define CCI_I2C_M0_RD_THRESHOLD_ADDR 0x00000120 #define CCI_I2C_M1_RD_THRESHOLD_ADDR 0x00000220 #define CCI_I2C_RD_THRESHOLD_VALUE 0x38 #define CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR 0x00000c00 #define DEBUG_TOP_REG_START 0x0 #define DEBUG_TOP_REG_COUNT 14 #define DEBUG_MASTER_REG_START 0x100 #define DEBUG_MASTER_REG_COUNT 8 #define DEBUG_MASTER_REG_COUNT 9 #define DEBUG_MASTER_QUEUE_REG_START 0x300 #define DEBUG_MASTER_QUEUE_REG_COUNT 6 #define DEBUG_MASTER_QUEUE_REG_COUNT 7 #define DEBUG_INTR_REG_START 0xC00 #define DEBUG_INTR_REG_COUNT 7 #endif /* _CAM_CCI_HWREG_ */ Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +8 −1 Original line number Diff line number Diff line Loading @@ -2378,7 +2378,9 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; ctx_isp->substate_activated = ctx_isp->rdi_only_context ? CAM_ISP_CTX_ACTIVATED_APPLIED : CAM_ISP_CTX_ACTIVATED_SOF; CAM_ISP_CTX_ACTIVATED_APPLIED : (req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH : CAM_ISP_CTX_ACTIVATED_SOF; /* * Only place to change state before calling the hw due to Loading @@ -2396,6 +2398,11 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, goto end; } CAM_DBG(CAM_ISP, "start device success"); if (req_isp->num_fence_map_out) { list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); } end: return rc; } Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +195 −12 Original line number Diff line number Diff line Loading @@ -205,8 +205,6 @@ static void cam_cci_dump_registers(struct cci_device *cci_dev, CAM_INFO(CAM_CCI, "****CCI MASTER %d Registers ****", master); for (i = 0; i < DEBUG_MASTER_REG_COUNT; i++) { if (i == 6) continue; reg_offset = DEBUG_MASTER_REG_START + master*0x100 + i * 4; read_val = cam_io_r_mb(base + reg_offset); CAM_INFO(CAM_CCI, "offset = 0x%X value = 0x%X", Loading Loading @@ -867,6 +865,180 @@ static int32_t cam_cci_data_queue(struct cci_device *cci_dev, return rc; } static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, struct cam_cci_ctrl *c_ctrl) { int32_t rc = 0; uint32_t val = 0, i = 0; unsigned long rem_jiffies; int32_t read_words = 0, exp_words = 0; int32_t index = 0, first_byte = 0, total_read_words = 0; enum cci_i2c_master_t master; enum cci_i2c_queue_t queue = QUEUE_1; struct cci_device *cci_dev = NULL; struct cam_cci_read_cfg *read_cfg = NULL; struct cam_hw_soc_info *soc_info = NULL; void __iomem *base = NULL; cci_dev = v4l2_get_subdevdata(sd); master = c_ctrl->cci_info->cci_i2c_master; read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg; 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; } soc_info = &cci_dev->soc_info; base = soc_info->reg_map[0].mem_base; mutex_lock(&cci_dev->cci_master_info[master].mutex_q[queue]); /* * Todo: If there is a change in frequency of operation * Wait for previos transaction to complete */ /* Set the I2C Frequency */ rc = cam_cci_set_clk_param(cci_dev, c_ctrl); if (rc < 0) { CAM_ERR(CAM_CCI, "cam_cci_set_clk_param failed rc = %d", rc); goto rel_mutex; } /* * Call validate queue to make sure queue is empty before starting. * If this call fails, don't proceed with i2c_read call. This is to * avoid overflow / underflow of queue */ rc = cam_cci_validate_queue(cci_dev, cci_dev->cci_i2c_queue_info[master][queue].max_queue_size - 1, master, queue); if (rc < 0) { CAM_ERR(CAM_CCI, "Initial validataion failed rc %d", rc); goto rel_mutex; } if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) { CAM_ERR(CAM_CCI, "More than max retries"); goto rel_mutex; } if (read_cfg->data == NULL) { CAM_ERR(CAM_CCI, "Data ptr is NULL"); goto rel_mutex; } if (read_cfg->addr_type >= CAMERA_SENSOR_I2C_TYPE_MAX) { CAM_ERR(CAM_CCI, "failed : Invalid addr type: %u", read_cfg->addr_type); rc = -EINVAL; goto rel_mutex; } CAM_DBG(CAM_CCI, "set param sid 0x%x retries %d id_map %d", c_ctrl->cci_info->sid, c_ctrl->cci_info->retries, c_ctrl->cci_info->id_map); val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 | c_ctrl->cci_info->retries << 16 | c_ctrl->cci_info->id_map << 18; rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = CCI_I2C_LOCK_CMD; rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4); for (i = 0; i < read_cfg->addr_type; i++) { val |= ((read_cfg->addr >> (i << 3)) & 0xFF) << ((read_cfg->addr_type - i) << 3); } rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = CCI_I2C_READ_CMD | (read_cfg->num_byte << 4); rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = CCI_I2C_UNLOCK_CMD; rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue); if (rc < 0) { CAM_DBG(CAM_CCI, "failed rc: %d", rc); goto rel_mutex; } val = cam_io_r_mb(base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + master * 0x200 + queue * 0x100); CAM_DBG(CAM_CCI, "cur word cnt 0x%x", val); cam_io_w_mb(val, base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + master * 0x200 + queue * 0x100); val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); exp_words = ((read_cfg->num_byte / 4) + 1); while (exp_words != total_read_words) { rem_jiffies = wait_for_completion_timeout( &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); if (!rem_jiffies) { rc = -ETIMEDOUT; val = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); CAM_ERR(CAM_CCI, "wait_for_completion_timeout rc = %d FIFO buf_lvl:0x%x", rc, val); #ifdef DUMP_CCI_REGISTERS cam_cci_dump_registers(cci_dev, master, queue); #endif cam_cci_flush_queue(cci_dev, master); goto rel_mutex; } read_words = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); total_read_words += read_words; do { val = cam_io_r_mb(base + CCI_I2C_M0_READ_DATA_ADDR + master * 0x100); for (i = 0; (i < 4) && (index < read_cfg->num_byte); i++) { CAM_DBG(CAM_CCI, "i:%d index:%d", i, index); if (!first_byte) { CAM_DBG(CAM_CCI, "sid 0x%x", val & 0xFF); first_byte++; } else { read_cfg->data[index] = (val >> (i * 8)) & 0xFF; CAM_DBG(CAM_CCI, "data[%d] 0x%x", index, read_cfg->data[index]); index++; } } } while (--read_words > 0); } rel_mutex: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); return rc; } static int32_t cam_cci_read(struct v4l2_subdev *sd, struct cam_cci_ctrl *c_ctrl) { Loading Loading @@ -1003,7 +1175,11 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, #endif if (rc == 0) rc = -ETIMEDOUT; CAM_ERR(CAM_CCI, "wait_for_completion_timeout rc = %d", rc); val = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); CAM_ERR(CAM_CCI, "wait_for_completion_timeout rc = %d FIFO buf_lvl: 0x%x", rc, val); cam_cci_flush_queue(cci_dev, master); goto rel_mutex; } else { Loading Loading @@ -1223,19 +1399,26 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd, read_bytes = read_cfg->num_byte; do { if (read_bytes > CCI_READ_MAX) read_cfg->num_byte = CCI_READ_MAX; if (read_bytes > CCI_I2C_MAX_BYTE_COUNT) read_cfg->num_byte = CCI_I2C_MAX_BYTE_COUNT; else read_cfg->num_byte = read_bytes; if (read_cfg->num_byte > CCI_READ_MAX) rc = cam_cci_burst_read(sd, c_ctrl); else rc = cam_cci_read(sd, c_ctrl); if (rc < 0) { CAM_ERR(CAM_CCI, "failed rc %d", rc); if (!rc) { CAM_ERR(CAM_CCI, "failed to read rc:%d", rc); goto ERROR; } if (read_bytes > CCI_READ_MAX) { read_cfg->addr += CCI_READ_MAX; read_cfg->data += CCI_READ_MAX; read_bytes -= CCI_READ_MAX; if (read_bytes > CCI_I2C_MAX_BYTE_COUNT) { read_cfg->addr += (CCI_I2C_MAX_BYTE_COUNT / read_cfg->data_type); read_cfg->data += CCI_I2C_MAX_BYTE_COUNT; read_bytes -= CCI_I2C_MAX_BYTE_COUNT; } else { read_bytes = 0; } Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +46 −16 Original line number Diff line number Diff line Loading @@ -60,18 +60,23 @@ static long cam_cci_subdev_compat_ioctl(struct v4l2_subdev *sd, irqreturn_t cam_cci_irq(int irq_num, void *data) { uint32_t irq; uint32_t irq_status0 = 0; uint32_t irq_status1 = 0; struct cci_device *cci_dev = data; struct cam_hw_soc_info *soc_info = &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; bool burst_read_assert = false; irq = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); cam_io_w_mb(irq, base + CCI_IRQ_CLEAR_0_ADDR); irq_status0 = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR); irq_status1 = cam_io_r_mb(base + CCI_IRQ_STATUS_1_ADDR); cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR); cam_io_w_mb(irq_status1, base + CCI_IRQ_CLEAR_1_ADDR); cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); if (irq & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) { CAM_DBG(CAM_CCI, "irq0:%x irq1:%x", irq_status0, irq_status1); if (irq_status0 & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) { if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) { cci_dev->cci_master_info[MASTER_0].reset_pending = FALSE; Loading @@ -85,11 +90,24 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].reset_complete); } } if (irq & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) { if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) && (irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD)) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); burst_read_assert = true; } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) && (!burst_read_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) && (!burst_read_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; Loading @@ -106,7 +124,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_0].lock_q[QUEUE_0], flags); } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_0]; Loading @@ -123,11 +141,23 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_0].lock_q[QUEUE_1], flags); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) { if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) && (irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD)) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); burst_read_assert = true; } if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) && (!burst_read_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) && (!burst_read_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; Loading @@ -144,7 +174,7 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].lock_q[QUEUE_0], flags); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; cci_master_info = &cci_dev->cci_master_info[MASTER_1]; Loading @@ -161,27 +191,27 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].lock_q[QUEUE_1], flags); } if (irq & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE; cam_io_w_mb(CCI_M0_RESET_RMSK, base + CCI_RESET_CMD_ADDR); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK) { cci_dev->cci_master_info[MASTER_1].reset_pending = TRUE; cam_io_w_mb(CCI_M1_RESET_RMSK, base + CCI_RESET_CMD_ADDR); } if (irq & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) { cci_dev->cci_master_info[MASTER_0].status = -EINVAL; cam_io_w_mb(CCI_M0_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR); CAM_DBG(CAM_CCI, "MASTER_0 error 0x%x", irq); CAM_DBG(CAM_CCI, "MASTER_0 error 0x%x", irq_status0); } if (irq & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) { if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) { cci_dev->cci_master_info[MASTER_1].status = -EINVAL; cam_io_w_mb(CCI_M1_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR); CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq); CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0); } return IRQ_HANDLED; } Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +3 −7 Original line number Diff line number Diff line Loading @@ -65,19 +65,14 @@ #define MAX_LRME_V4l2_EVENTS 30 /* Max bytes that can be read per CCI read transaction */ #define CCI_READ_MAX 12 #define CCI_READ_MAX 256 #define CCI_I2C_READ_MAX_RETRIES 3 #define CCI_I2C_MAX_READ 8192 #define CCI_I2C_MAX_WRITE 8192 #define CCI_I2C_MAX_BYTE_COUNT 65535 #define CAMX_CCI_DEV_NAME "cam-cci-driver" /* Max bytes that can be read per CCI read transaction */ #define CCI_READ_MAX 12 #define CCI_I2C_READ_MAX_RETRIES 3 #define CCI_I2C_MAX_READ 8192 #define CCI_I2C_MAX_WRITE 8192 #define MAX_CCI 2 #define PRIORITY_QUEUE (QUEUE_0) Loading Loading @@ -127,6 +122,7 @@ struct cam_cci_read_cfg { uint16_t addr_type; uint8_t *data; uint16_t num_byte; uint16_t data_type; }; struct cam_cci_i2c_queue_info { Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h +11 −2 Original line number Diff line number Diff line Loading @@ -43,27 +43,36 @@ #define CCI_I2C_M0_Q0_LOAD_DATA_ADDR 0x00000310 #define CCI_IRQ_MASK_0_ADDR 0x00000c04 #define CCI_IRQ_MASK_0_RMSK 0x7fff7ff7 #define CCI_IRQ_MASK_1_ADDR 0x00000c10 #define CCI_IRQ_MASK_1_RMSK 0x00110000 #define CCI_IRQ_CLEAR_0_ADDR 0x00000c08 #define CCI_IRQ_CLEAR_1_ADDR 0x00000c14 #define CCI_IRQ_STATUS_0_ADDR 0x00000c0c #define CCI_IRQ_STATUS_1_ADDR 0x00000c18 #define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK_BMSK 0x4000000 #define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK_BMSK 0x2000000 #define CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK 0x1000000 #define CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT_BMSK 0x100000 #define CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK 0x10000 #define CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK 0x1000 #define CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD 0x100000 #define CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT_BMSK 0x100 #define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK 0x10 #define CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK 0x18000EE6 #define CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK 0x60EE6000 #define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK 0x1 #define CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD 0x10000 #define CCI_I2C_M0_RD_THRESHOLD_ADDR 0x00000120 #define CCI_I2C_M1_RD_THRESHOLD_ADDR 0x00000220 #define CCI_I2C_RD_THRESHOLD_VALUE 0x38 #define CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR 0x00000c00 #define DEBUG_TOP_REG_START 0x0 #define DEBUG_TOP_REG_COUNT 14 #define DEBUG_MASTER_REG_START 0x100 #define DEBUG_MASTER_REG_COUNT 8 #define DEBUG_MASTER_REG_COUNT 9 #define DEBUG_MASTER_QUEUE_REG_START 0x300 #define DEBUG_MASTER_QUEUE_REG_COUNT 6 #define DEBUG_MASTER_QUEUE_REG_COUNT 7 #define DEBUG_INTR_REG_START 0xC00 #define DEBUG_INTR_REG_COUNT 7 #endif /* _CAM_CCI_HWREG_ */