Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +80 −11 Original line number Diff line number Diff line Loading @@ -869,8 +869,8 @@ 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; uint32_t val = 0, i = 0, j = 0; unsigned long rem_jiffies, flags; 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; Loading Loading @@ -989,11 +989,13 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); exp_words = ((read_cfg->num_byte / 4) + 1); CAM_DBG(CAM_CCI, "waiting for threshold [exp_words %d]", exp_words); while (exp_words != total_read_words) { while (total_read_words != exp_words) { rem_jiffies = wait_for_completion_timeout( &cci_dev->cci_master_info[master].reset_complete, &cci_dev->cci_master_info[master].th_complete, CCI_TIMEOUT); if (!rem_jiffies) { rc = -ETIMEDOUT; Loading @@ -1012,6 +1014,14 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, read_words = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); if (read_words <= 0) { CAM_DBG(CAM_CCI, "FIFO Buffer lvl is 0"); continue; } j++; CAM_DBG(CAM_CCI, "Iteration: %u read_words %d", j, read_words); total_read_words += read_words; while (read_words > 0) { val = cam_io_r_mb(base + Loading @@ -1033,8 +1043,55 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, } read_words--; } CAM_DBG(CAM_CCI, "Iteraion:%u total_read_words %d", j, total_read_words); spin_lock_irqsave(&cci_dev->lock_status, flags); if (cci_dev->irq_status1) { CAM_DBG(CAM_CCI, "clear irq_status1:%x", cci_dev->irq_status1); cam_io_w_mb(cci_dev->irq_status1, base + CCI_IRQ_CLEAR_1_ADDR); cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); cci_dev->irq_status1 = 0; } spin_unlock_irqrestore(&cci_dev->lock_status, flags); if (total_read_words == exp_words) { /* * This wait is for RD_DONE irq, if RD_DONE is * triggered we will call complete on both threshold * & read done waits. As part of the threshold wait * we will be draining the entire buffer out. This * wait is to compensate for the complete invoked for * RD_DONE exclusively. */ 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, "Failed to receive RD_DONE irq 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; } break; } } CAM_DBG(CAM_CCI, "Burst read successful words_read %d", total_read_words); rel_mutex: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); return rc; Loading Loading @@ -1166,7 +1223,8 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); CAM_DBG(CAM_CCI, "wait_for_completion_timeout"); CAM_DBG(CAM_CCI, "waiting_for_rd_done [exp_words: %d]", exp_words); rc = wait_for_completion_timeout( &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); Loading Loading @@ -1221,7 +1279,6 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, } rel_mutex: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); return rc; } Loading Loading @@ -1400,23 +1457,34 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd, } read_bytes = read_cfg->num_byte; /* * To avoid any conflicts due to back to back trigger of * THRESHOLD irq's, we reinit the threshold wait before * we load the burst read cmd. */ reinit_completion(&cci_dev->cci_master_info[master].th_complete); CAM_DBG(CAM_CCI, "Bytes to read %u", read_bytes); do { if (read_bytes > CCI_I2C_MAX_BYTE_COUNT) 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) if (read_cfg->num_byte >= CCI_READ_MAX) { cci_dev->is_burst_read = true; rc = cam_cci_burst_read(sd, c_ctrl); else } else { 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_I2C_MAX_BYTE_COUNT) { 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; Loading @@ -1427,6 +1495,7 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd, } while (read_bytes); ERROR: cci_dev->is_burst_read = false; return rc; } Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +39 −13 Original line number Diff line number Diff line Loading @@ -67,15 +67,12 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; bool burst_read_assert = false; bool rd_done_th_assert = false; 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); 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 = Loading @@ -94,18 +91,23 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) 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; rd_done_th_assert = true; complete(&cci_dev->cci_master_info[MASTER_0].th_complete); 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)) { (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; rd_done_th_assert = true; if (cci_dev->is_burst_read) complete( &cci_dev->cci_master_info[MASTER_0].th_complete); complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) && (!burst_read_assert)) { (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); complete(&cci_dev->cci_master_info[MASTER_0].th_complete); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; Loading Loading @@ -144,18 +146,23 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) 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; rd_done_th_assert = true; complete(&cci_dev->cci_master_info[MASTER_1].th_complete); 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)) { (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; rd_done_th_assert = true; if (cci_dev->is_burst_read) complete( &cci_dev->cci_master_info[MASTER_1].th_complete); complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) && (!burst_read_assert)) { (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); complete(&cci_dev->cci_master_info[MASTER_1].th_complete); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; Loading Loading @@ -191,6 +198,12 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].lock_q[QUEUE_1], flags); } if (irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_PAUSE) CAM_DBG(CAM_CCI, "RD_PAUSE ON MASTER_0"); if (irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_PAUSE) CAM_DBG(CAM_CCI, "RD_PAUSE ON MASTER_1"); 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, Loading @@ -213,6 +226,19 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) base + CCI_HALT_REQ_ADDR); CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0); } if ((rd_done_th_assert) || (!cci_dev->is_burst_read)) { cam_io_w_mb(irq_status1, base + CCI_IRQ_CLEAR_1_ADDR); CAM_DBG(CAM_CCI, "clear irq_status0:%x irq_status1:%x", irq_status0, irq_status1); } else { spin_lock_irqsave(&cci_dev->lock_status, flags); cci_dev->irq_status1 |= irq_status1; spin_unlock_irqrestore(&cci_dev->lock_status, flags); } cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR); cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); return IRQ_HANDLED; } Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +9 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ struct cam_cci_master_info { uint8_t reset_pending; struct mutex mutex; struct completion reset_complete; struct completion th_complete; struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; Loading Loading @@ -194,6 +195,11 @@ enum cam_cci_state_t { * @cci_wait_sync_cfg: CCI sync config * @cycles_per_us: Cycles per micro sec * @payload_size: CCI packet payload size * @irq_status1: Store irq_status1 to be cleared after * draining FIFO buffer for burst read * @lock_status: to protect changes to irq_status1 * @is_burst_read: Flag to determine if we are performing * a burst read operation or not */ struct cci_device { struct v4l2_subdev subdev; Loading @@ -218,6 +224,9 @@ struct cci_device { uint8_t payload_size; char device_name[20]; uint32_t cpas_handle; uint32_t irq_status1; spinlock_t lock_status; bool is_burst_read; }; enum cam_cci_i2c_cmd_type { Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h +3 −1 Original line number Diff line number Diff line Loading @@ -56,15 +56,17 @@ #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_1_I2C_M1_RD_PAUSE 0x200000 #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_IRQ_STATUS_1_I2C_M0_RD_PAUSE 0x20000 #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_I2C_RD_THRESHOLD_VALUE 0x30 #define CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR 0x00000c00 #define DEBUG_TOP_REG_START 0x0 Loading drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +3 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) mutex_init(&new_cci_dev->cci_master_info[i].mutex); init_completion( &new_cci_dev->cci_master_info[i].reset_complete); init_completion( &new_cci_dev->cci_master_info[i].th_complete); for (j = 0; j < NUM_QUEUES; j++) { mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); Loading @@ -208,6 +210,7 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) &new_cci_dev->cci_master_info[i].lock_q[j]); } } spin_lock_init(&new_cci_dev->lock_status); } static void cam_cci_init_default_clk_params(struct cci_device *cci_dev, Loading Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_core.c +80 −11 Original line number Diff line number Diff line Loading @@ -869,8 +869,8 @@ 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; uint32_t val = 0, i = 0, j = 0; unsigned long rem_jiffies, flags; 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; Loading Loading @@ -989,11 +989,13 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); exp_words = ((read_cfg->num_byte / 4) + 1); CAM_DBG(CAM_CCI, "waiting for threshold [exp_words %d]", exp_words); while (exp_words != total_read_words) { while (total_read_words != exp_words) { rem_jiffies = wait_for_completion_timeout( &cci_dev->cci_master_info[master].reset_complete, &cci_dev->cci_master_info[master].th_complete, CCI_TIMEOUT); if (!rem_jiffies) { rc = -ETIMEDOUT; Loading @@ -1012,6 +1014,14 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, read_words = cam_io_r_mb(base + CCI_I2C_M0_READ_BUF_LEVEL_ADDR + master * 0x100); if (read_words <= 0) { CAM_DBG(CAM_CCI, "FIFO Buffer lvl is 0"); continue; } j++; CAM_DBG(CAM_CCI, "Iteration: %u read_words %d", j, read_words); total_read_words += read_words; while (read_words > 0) { val = cam_io_r_mb(base + Loading @@ -1033,8 +1043,55 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd, } read_words--; } CAM_DBG(CAM_CCI, "Iteraion:%u total_read_words %d", j, total_read_words); spin_lock_irqsave(&cci_dev->lock_status, flags); if (cci_dev->irq_status1) { CAM_DBG(CAM_CCI, "clear irq_status1:%x", cci_dev->irq_status1); cam_io_w_mb(cci_dev->irq_status1, base + CCI_IRQ_CLEAR_1_ADDR); cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); cci_dev->irq_status1 = 0; } spin_unlock_irqrestore(&cci_dev->lock_status, flags); if (total_read_words == exp_words) { /* * This wait is for RD_DONE irq, if RD_DONE is * triggered we will call complete on both threshold * & read done waits. As part of the threshold wait * we will be draining the entire buffer out. This * wait is to compensate for the complete invoked for * RD_DONE exclusively. */ 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, "Failed to receive RD_DONE irq 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; } break; } } CAM_DBG(CAM_CCI, "Burst read successful words_read %d", total_read_words); rel_mutex: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); return rc; Loading Loading @@ -1166,7 +1223,8 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, val = 1 << ((master * 2) + queue); cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR); CAM_DBG(CAM_CCI, "wait_for_completion_timeout"); CAM_DBG(CAM_CCI, "waiting_for_rd_done [exp_words: %d]", exp_words); rc = wait_for_completion_timeout( &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); Loading Loading @@ -1221,7 +1279,6 @@ static int32_t cam_cci_read(struct v4l2_subdev *sd, } rel_mutex: mutex_unlock(&cci_dev->cci_master_info[master].mutex_q[queue]); return rc; } Loading Loading @@ -1400,23 +1457,34 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd, } read_bytes = read_cfg->num_byte; /* * To avoid any conflicts due to back to back trigger of * THRESHOLD irq's, we reinit the threshold wait before * we load the burst read cmd. */ reinit_completion(&cci_dev->cci_master_info[master].th_complete); CAM_DBG(CAM_CCI, "Bytes to read %u", read_bytes); do { if (read_bytes > CCI_I2C_MAX_BYTE_COUNT) 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) if (read_cfg->num_byte >= CCI_READ_MAX) { cci_dev->is_burst_read = true; rc = cam_cci_burst_read(sd, c_ctrl); else } else { 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_I2C_MAX_BYTE_COUNT) { 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; Loading @@ -1427,6 +1495,7 @@ static int32_t cam_cci_read_bytes(struct v4l2_subdev *sd, } while (read_bytes); ERROR: cci_dev->is_burst_read = false; return rc; } Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.c +39 −13 Original line number Diff line number Diff line Loading @@ -67,15 +67,12 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->soc_info; void __iomem *base = soc_info->reg_map[0].mem_base; unsigned long flags; bool burst_read_assert = false; bool rd_done_th_assert = false; 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); 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 = Loading @@ -94,18 +91,23 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) 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; rd_done_th_assert = true; complete(&cci_dev->cci_master_info[MASTER_0].th_complete); 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)) { (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; rd_done_th_assert = true; if (cci_dev->is_burst_read) complete( &cci_dev->cci_master_info[MASTER_0].th_complete); complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) && (!burst_read_assert)) { (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_0].status = 0; complete(&cci_dev->cci_master_info[MASTER_0].reset_complete); complete(&cci_dev->cci_master_info[MASTER_0].th_complete); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; Loading Loading @@ -144,18 +146,23 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) 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; rd_done_th_assert = true; complete(&cci_dev->cci_master_info[MASTER_1].th_complete); 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)) { (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; rd_done_th_assert = true; if (cci_dev->is_burst_read) complete( &cci_dev->cci_master_info[MASTER_1].th_complete); complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); } if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) && (!burst_read_assert)) { (!rd_done_th_assert)) { cci_dev->cci_master_info[MASTER_1].status = 0; complete(&cci_dev->cci_master_info[MASTER_1].reset_complete); complete(&cci_dev->cci_master_info[MASTER_1].th_complete); } if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT_BMSK) { struct cam_cci_master_info *cci_master_info; Loading Loading @@ -191,6 +198,12 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) &cci_dev->cci_master_info[MASTER_1].lock_q[QUEUE_1], flags); } if (irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_PAUSE) CAM_DBG(CAM_CCI, "RD_PAUSE ON MASTER_0"); if (irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_PAUSE) CAM_DBG(CAM_CCI, "RD_PAUSE ON MASTER_1"); 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, Loading @@ -213,6 +226,19 @@ irqreturn_t cam_cci_irq(int irq_num, void *data) base + CCI_HALT_REQ_ADDR); CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0); } if ((rd_done_th_assert) || (!cci_dev->is_burst_read)) { cam_io_w_mb(irq_status1, base + CCI_IRQ_CLEAR_1_ADDR); CAM_DBG(CAM_CCI, "clear irq_status0:%x irq_status1:%x", irq_status0, irq_status1); } else { spin_lock_irqsave(&cci_dev->lock_status, flags); cci_dev->irq_status1 |= irq_status1; spin_unlock_irqrestore(&cci_dev->lock_status, flags); } cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR); cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR); return IRQ_HANDLED; } Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_dev.h +9 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ struct cam_cci_master_info { uint8_t reset_pending; struct mutex mutex; struct completion reset_complete; struct completion th_complete; struct mutex mutex_q[NUM_QUEUES]; struct completion report_q[NUM_QUEUES]; atomic_t done_pending[NUM_QUEUES]; Loading Loading @@ -194,6 +195,11 @@ enum cam_cci_state_t { * @cci_wait_sync_cfg: CCI sync config * @cycles_per_us: Cycles per micro sec * @payload_size: CCI packet payload size * @irq_status1: Store irq_status1 to be cleared after * draining FIFO buffer for burst read * @lock_status: to protect changes to irq_status1 * @is_burst_read: Flag to determine if we are performing * a burst read operation or not */ struct cci_device { struct v4l2_subdev subdev; Loading @@ -218,6 +224,9 @@ struct cci_device { uint8_t payload_size; char device_name[20]; uint32_t cpas_handle; uint32_t irq_status1; spinlock_t lock_status; bool is_burst_read; }; enum cam_cci_i2c_cmd_type { Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_hwreg.h +3 −1 Original line number Diff line number Diff line Loading @@ -56,15 +56,17 @@ #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_1_I2C_M1_RD_PAUSE 0x200000 #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_IRQ_STATUS_1_I2C_M0_RD_PAUSE 0x20000 #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_I2C_RD_THRESHOLD_VALUE 0x30 #define CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR 0x00000c00 #define DEBUG_TOP_REG_START 0x0 Loading
drivers/media/platform/msm/camera/cam_sensor_module/cam_cci/cam_cci_soc.c +3 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) mutex_init(&new_cci_dev->cci_master_info[i].mutex); init_completion( &new_cci_dev->cci_master_info[i].reset_complete); init_completion( &new_cci_dev->cci_master_info[i].th_complete); for (j = 0; j < NUM_QUEUES; j++) { mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]); Loading @@ -208,6 +210,7 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev) &new_cci_dev->cci_master_info[i].lock_q[j]); } } spin_lock_init(&new_cci_dev->lock_status); } static void cam_cci_init_default_clk_params(struct cci_device *cci_dev, Loading