From fa080688013d21e43352bf1925fba2f2f30c137e Mon Sep 17 00:00:00 2001 From: Jigarkumar Zala Date: Mon, 16 Mar 2020 12:20:57 -0700 Subject: [PATCH] msm: camera: csiphy: Update logic for lane enablement Currently lane enablement is happening as a part of lanemask field, which is send by UMD. Lane enablement should be purely depends on laneCnt and laneAssign attributes. Also, combo mode sensors needs to come with combo mode flag set from the UMD. This change updates the logic for lane enablement with respect to laneAssign and laneCnt, and also covers all combomode selection as per the request. This change also enables the sensors to acquire and streamon/streamoff at anytime in session. CRs-Fixed: 2677450 Change-Id: I4f0d3ffd7245a931c273611c9c4b7e503c038664 Signed-off-by: Jigarkumar Zala --- .../cam_csiphy/cam_csiphy_core.c | 806 ++++++++++++------ .../cam_csiphy/cam_csiphy_dev.c | 24 +- .../cam_csiphy/cam_csiphy_dev.h | 154 ++-- .../cam_csiphy/cam_csiphy_soc.c | 33 +- .../cam_csiphy/cam_csiphy_soc.h | 5 +- .../include/cam_csiphy_1_2_3_hwreg.h | 1 + drivers/cam_utils/cam_compat.c | 10 +- include/uapi/camera/media/cam_sensor.h | 33 +- 8 files changed, 679 insertions(+), 387 deletions(-) diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 01c54cdd6c..f4d60b937c 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -34,17 +34,21 @@ int32_t cam_csiphy_get_instance_offset( struct csiphy_device *csiphy_dev, int32_t dev_handle) { - int32_t i; + int32_t i = 0; - if (csiphy_dev->acquire_count > - CSIPHY_MAX_INSTANCES) { - CAM_ERR(CAM_CSIPHY, "Invalid acquire count"); + if ((csiphy_dev->acquire_count > + csiphy_dev->session_max_device_support) || + (csiphy_dev->acquire_count < 0)) { + CAM_ERR(CAM_CSIPHY, + "Invalid acquire count: %d, Max supported device for session: %u", + csiphy_dev->acquire_count, + csiphy_dev->session_max_device_support); return -EINVAL; } for (i = 0; i < csiphy_dev->acquire_count; i++) { if (dev_handle == - csiphy_dev->bridge_intf.device_hdl[i]) + csiphy_dev->csiphy_info[i].hdl_data.device_hdl) break; } @@ -84,83 +88,138 @@ void cam_csiphy_reset(struct csiphy_device *csiphy_dev) } } -int32_t cam_csiphy_update_secure_info( - struct csiphy_device *csiphy_dev, - struct cam_csiphy_info *cam_cmd_csiphy_info, - struct cam_config_dev_cmd *cfg_dev) +static int32_t cam_csiphy_update_secure_info( + struct csiphy_device *csiphy_dev, int32_t index) { - uint32_t clock_lane, adj_lane_mask, temp, phy_mask_len; - int32_t offset; + uint32_t adj_lane_mask = 0; + uint16_t lane_assign = 0; + uint32_t phy_mask_len = 0; + uint8_t lane_cnt = 0; - if (csiphy_dev->acquire_count >= - CSIPHY_MAX_INSTANCES) { - CAM_ERR(CAM_CSIPHY, "Invalid acquire count"); - return -EINVAL; + lane_assign = csiphy_dev->csiphy_info[index].lane_assign; + lane_cnt = csiphy_dev->csiphy_info[index].lane_cnt; + + while (lane_cnt--) { + if ((lane_assign & 0xF) == 0x0) + adj_lane_mask |= 0x1; + else + adj_lane_mask |= (1 << (lane_assign & 0xF)); + + lane_assign >>= 4; } - offset = cam_csiphy_get_instance_offset(csiphy_dev, - cfg_dev->dev_handle); - if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) { - CAM_ERR(CAM_CSIPHY, "Invalid offset"); - return -EINVAL; - } - - if (cam_cmd_csiphy_info->combo_mode) - clock_lane = - csiphy_dev->ctrl_reg->csiphy_reg.csiphy_2ph_combo_ck_ln; - else - clock_lane = - csiphy_dev->ctrl_reg->csiphy_reg.csiphy_2ph_clock_lane; - - adj_lane_mask = cam_cmd_csiphy_info->lane_mask & LANE_MASK_2PH & - ~clock_lane; - temp = adj_lane_mask & (clock_lane - 1); - adj_lane_mask = - ((adj_lane_mask & (~(clock_lane - 1))) >> 1) | temp; - - if (cam_cmd_csiphy_info->csiphy_3phase) - adj_lane_mask = cam_cmd_csiphy_info->lane_mask & LANE_MASK_3PH; - - csiphy_dev->csiphy_info.secure_mode[offset] = 1; - if (csiphy_dev->hw_version == CSIPHY_VERSION_V201) { phy_mask_len = CAM_CSIPHY_MAX_DPHY_LANES + CAM_CSIPHY_MAX_CPHY_LANES + 1; } else if (csiphy_dev->hw_version == CSIPHY_VERSION_V121) { phy_mask_len = (csiphy_dev->soc_info.index < MAX_PHY_MSK_PER_REG) ? - CAM_CSIPHY_MAX_DPHY_LANES + CAM_CSIPHY_MAX_CPHY_LANES : - CAM_CSIPHY_MAX_DPHY_LANES + - CAM_CSIPHY_MAX_CPHY_LANES + 1; + (CAM_CSIPHY_MAX_DPHY_LANES + CAM_CSIPHY_MAX_CPHY_LANES) + : (CAM_CSIPHY_MAX_DPHY_LANES + + CAM_CSIPHY_MAX_CPHY_LANES + 1); } else { phy_mask_len = CAM_CSIPHY_MAX_DPHY_LANES + CAM_CSIPHY_MAX_CPHY_LANES; } if (csiphy_dev->soc_info.index < MAX_PHY_MSK_PER_REG) { - csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = - ((uint64_t)adj_lane_mask) << - (csiphy_dev->soc_info.index * phy_mask_len + - (!cam_cmd_csiphy_info->csiphy_3phase) * + csiphy_dev->csiphy_info[index].csiphy_cpas_cp_reg_mask = + adj_lane_mask << + ((csiphy_dev->soc_info.index * phy_mask_len) + + (!csiphy_dev->csiphy_info[index].csiphy_3phase) * (CAM_CSIPHY_MAX_CPHY_LANES)); } else { - csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = + csiphy_dev->csiphy_info[index].csiphy_cpas_cp_reg_mask = ((uint64_t)adj_lane_mask) << ((csiphy_dev->soc_info.index - MAX_PHY_MSK_PER_REG) * phy_mask_len + SEC_LANE_CP_REG_LEN + - (!cam_cmd_csiphy_info->csiphy_3phase) * + (!csiphy_dev->csiphy_info[index].csiphy_3phase) * (CAM_CSIPHY_MAX_CPHY_LANES)); } + CAM_DBG(CAM_CSIPHY, "csi phy idx:%d, cp_reg_mask:0x%lx", csiphy_dev->soc_info.index, - csiphy_dev->csiphy_cpas_cp_reg_mask[offset]); + csiphy_dev->csiphy_info[index].csiphy_cpas_cp_reg_mask); + return 0; } +static int cam_csiphy_get_lane_enable( + struct csiphy_device *csiphy, int index, uint32_t *lane_enable) +{ + uint32_t lane_select = 0; + uint16_t lane_assign = csiphy->csiphy_info[index].lane_assign; + uint8_t lane_cnt = csiphy->csiphy_info[index].lane_cnt; + int rc = 0; + + while (lane_cnt--) { + if (csiphy->csiphy_info[index].csiphy_3phase) { + switch (lane_assign & 0xF) { + case 0x0: + lane_select |= CPHY_LANE_0; + break; + case 0x1: + lane_select |= CPHY_LANE_1; + break; + case 0x2: + lane_select |= CPHY_LANE_2; + break; + default: + CAM_ERR(CAM_CSIPHY, + "Wrong lane configuration for CPHY : %d", + lane_assign); + *lane_enable = 0; + return -EINVAL; + } + } else { + switch (lane_assign & 0xF) { + case 0x0: + lane_select |= DPHY_LANE_0; + lane_select |= DPHY_CLK_LN; + break; + case 0x1: + lane_select |= DPHY_LANE_1; + lane_select |= DPHY_CLK_LN; + break; + case 0x2: + lane_select |= DPHY_LANE_2; + if (csiphy->combo_mode) + lane_select |= DPHY_LANE_3; + else + lane_select |= DPHY_CLK_LN; + break; + case 0x3: + if (csiphy->combo_mode) { + CAM_ERR(CAM_CSIPHY, + "Wrong lane configuration for DPHYCombo: %d", + lane_assign); + *lane_enable = 0; + return -EINVAL; + } + lane_select |= DPHY_LANE_3; + lane_select |= DPHY_CLK_LN; + break; + default: + CAM_ERR(CAM_CSIPHY, + "Wrong lane configuration for DPHY: %d", + lane_assign); + *lane_enable = 0; + return -EINVAL; + } + } + lane_assign >>= 4; + } + + CAM_DBG(CAM_CSIPHY, "Lane_enable: 0x%x", lane_enable); + *lane_enable = lane_select; + + return rc; +} + int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, struct cam_config_dev_cmd *cfg_dev) { - int32_t rc = 0; + int rc = 0; uintptr_t generic_ptr; uintptr_t generic_pkt_ptr; struct cam_packet *csl_packet = NULL; @@ -169,6 +228,8 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, struct cam_csiphy_info *cam_cmd_csiphy_info = NULL; size_t len; size_t remain_len; + int index; + uint32_t lane_enable = 0; if (!cfg_dev || !csiphy_dev) { CAM_ERR(CAM_CSIPHY, "Invalid Args"); @@ -227,46 +288,73 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, cmd_buf += cmd_desc->offset / 4; cam_cmd_csiphy_info = (struct cam_csiphy_info *)cmd_buf; - csiphy_dev->config_count++; - csiphy_dev->csiphy_info.lane_cnt += cam_cmd_csiphy_info->lane_cnt; - csiphy_dev->csiphy_info.lane_mask |= cam_cmd_csiphy_info->lane_mask; - csiphy_dev->csiphy_info.csiphy_3phase = - cam_cmd_csiphy_info->csiphy_3phase; - csiphy_dev->csiphy_info.combo_mode |= cam_cmd_csiphy_info->combo_mode; - if (cam_cmd_csiphy_info->combo_mode == 1) { - csiphy_dev->csiphy_info.settle_time_combo_sensor = - cam_cmd_csiphy_info->settle_time; - csiphy_dev->csiphy_info.data_rate_combo_sensor = - cam_cmd_csiphy_info->data_rate; - } else { - csiphy_dev->csiphy_info.settle_time = - cam_cmd_csiphy_info->settle_time; - csiphy_dev->csiphy_info.data_rate = - cam_cmd_csiphy_info->data_rate; + index = cam_csiphy_get_instance_offset(csiphy_dev, cfg_dev->dev_handle); + if (index < 0 || index >= csiphy_dev->session_max_device_support) { + CAM_ERR(CAM_CSIPHY, "index in invalid: %d", index); + return -EINVAL; } + csiphy_dev->csiphy_info[index].lane_cnt = cam_cmd_csiphy_info->lane_cnt; + csiphy_dev->csiphy_info[index].lane_assign = + cam_cmd_csiphy_info->lane_assign; + + csiphy_dev->csiphy_info[index].settle_time = + cam_cmd_csiphy_info->settle_time; + csiphy_dev->csiphy_info[index].data_rate = + cam_cmd_csiphy_info->data_rate; + csiphy_dev->csiphy_info[index].secure_mode = + cam_cmd_csiphy_info->secure_mode; + + rc = cam_csiphy_get_lane_enable(csiphy_dev, index, &lane_enable); + if (rc) { + CAM_ERR(CAM_CSIPHY, "Wrong lane configuration: %d", + csiphy_dev->csiphy_info[index].lane_assign); + if ((csiphy_dev->combo_mode) || + (csiphy_dev->cphy_dphy_combo_mode)) { + CAM_DBG(CAM_CSIPHY, + "Resetting error to zero for other devices to configure"); + rc = 0; + } + lane_enable = 0; + csiphy_dev->csiphy_info[index].lane_enable = lane_enable; + goto reset_settings; + } + + csiphy_dev->csiphy_info[index].lane_enable = lane_enable; if (cam_cmd_csiphy_info->secure_mode == 1) cam_csiphy_update_secure_info(csiphy_dev, - cam_cmd_csiphy_info, cfg_dev); + index); + + csiphy_dev->config_count++; CAM_DBG(CAM_CSIPHY, - "phy version_%d, lane count:%d, mask:0x%x", + "phy version:%d, phy_idx: %d", csiphy_dev->hw_version, - csiphy_dev->csiphy_info.lane_cnt, - csiphy_dev->csiphy_info.lane_mask - ); + csiphy_dev->soc_info.index); CAM_DBG(CAM_CSIPHY, "3phase:%d, combo mode:%d, secure mode:%d", - csiphy_dev->csiphy_info.csiphy_3phase, - csiphy_dev->csiphy_info.combo_mode, - cam_cmd_csiphy_info->secure_mode - ); + csiphy_dev->csiphy_info[index].csiphy_3phase, + csiphy_dev->combo_mode, + cam_cmd_csiphy_info->secure_mode); CAM_DBG(CAM_CSIPHY, - "phy idx:%d, settle time:%d, datarate:%d", - csiphy_dev->soc_info.index, - csiphy_dev->csiphy_info.settle_time, - csiphy_dev->csiphy_info.data_rate); + "lane_cnt: 0x%x, lane_assign: 0x%x, lane_enable: 0x%x, settle time:%llu, datarate:%llu", + csiphy_dev->csiphy_info[index].lane_cnt, + csiphy_dev->csiphy_info[index].lane_assign, + csiphy_dev->csiphy_info[index].lane_enable, + csiphy_dev->csiphy_info[index].settle_time, + csiphy_dev->csiphy_info[index].data_rate); + + return rc; + +reset_settings: + csiphy_dev->csiphy_info[index].lane_cnt = 0; + csiphy_dev->csiphy_info[index].lane_assign = 0; + csiphy_dev->csiphy_info[index].lane_enable = 0; + csiphy_dev->csiphy_info[index].settle_time = 0; + csiphy_dev->csiphy_info[index].data_rate = 0; + csiphy_dev->csiphy_info[index].secure_mode = 0; + csiphy_dev->csiphy_info[index].hdl_data.device_hdl = -1; return rc; } @@ -284,7 +372,8 @@ void cam_csiphy_cphy_irq_config(struct csiphy_device *csiphy_dev) csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr); } -void cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device) +static void cam_csiphy_cphy_data_rate_config( + struct csiphy_device *csiphy_device, int32_t idx) { int i = 0, j = 0; uint64_t phy_data_rate = 0; @@ -300,7 +389,7 @@ void cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device) return; } - phy_data_rate = csiphy_device->csiphy_info.data_rate; + phy_data_rate = csiphy_device->csiphy_info[idx].data_rate; csiphybase = csiphy_device->soc_info.reg_map[0].mem_base; settings_table = @@ -319,8 +408,8 @@ void cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device) if (phy_data_rate > bandwidth) { CAM_DBG(CAM_CSIPHY, - "Skipping table [%d] %llu required: %llu", - i, bandwidth, phy_data_rate); + "Skipping table [%d] %llu required: %llu", + i, bandwidth, phy_data_rate); continue; } @@ -393,82 +482,124 @@ irqreturn_t cam_csiphy_irq(int irq_num, void *data) return IRQ_HANDLED; } -int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev) +int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev, + int32_t dev_handle) { int32_t rc = 0; - uint32_t lane_enable = 0, mask = 1, size = 0; - uint16_t lane_mask = 0, i = 0, cfg_size = 0, temp = 0; - uint8_t lane_cnt, lane_pos = 0; + uint32_t lane_enable = 0; + uint32_t size = 0; + uint16_t i = 0, cfg_size = 0; + uint16_t lane_assign = 0; + uint8_t lane_cnt; + int max_lanes = 0; uint16_t settle_cnt = 0; uint64_t intermediate_var; + uint8_t lane_pos = 0; + int index; void __iomem *csiphybase; struct csiphy_reg_t *csiphy_common_reg = NULL; struct csiphy_reg_t (*reg_array)[MAX_SETTINGS_PER_LANE]; - - lane_cnt = csiphy_dev->csiphy_info.lane_cnt; + bool is_3phase = false; csiphybase = csiphy_dev->soc_info.reg_map[0].mem_base; + CAM_DBG(CAM_CSIPHY, "ENTER"); if (!csiphybase) { CAM_ERR(CAM_CSIPHY, "csiphybase NULL"); return -EINVAL; } - if (!csiphy_dev->csiphy_info.csiphy_3phase) { - if (csiphy_dev->csiphy_info.combo_mode == 1) - reg_array = - csiphy_dev->ctrl_reg->csiphy_2ph_combo_mode_reg; - else - reg_array = - csiphy_dev->ctrl_reg->csiphy_2ph_reg; - csiphy_dev->num_irq_registers = 11; - cfg_size = - csiphy_dev->ctrl_reg->csiphy_reg.csiphy_2ph_config_array_size; + index = cam_csiphy_get_instance_offset(csiphy_dev, dev_handle); + if (index < 0 || index >= csiphy_dev->session_max_device_support) { + CAM_ERR(CAM_CSIPHY, "index is invalid: %d", index); + return -EINVAL; + } - lane_mask = csiphy_dev->csiphy_info.lane_mask & LANE_MASK_2PH; - for (i = 0; i < MAX_DPHY_DATA_LN; i++) { - if (mask == 0x2) { - if (lane_mask & mask) - lane_enable |= 0x80; - i--; - } else if (lane_mask & mask) { - lane_enable |= 0x1 << (i<<1); - } - mask <<= 1; - } - } else { - if (csiphy_dev->csiphy_info.combo_mode == 1) { - if (csiphy_dev->ctrl_reg->csiphy_2ph_3ph_mode_reg) - reg_array = - csiphy_dev->ctrl_reg->csiphy_2ph_3ph_mode_reg; - else { + CAM_DBG(CAM_CSIPHY, + "Index: %d: expected dev_hdl: 0x%x : derived dev_hdl: 0x%x", + index, dev_handle, + csiphy_dev->csiphy_info[index].hdl_data.device_hdl); + csiphy_dev->num_irq_registers = 11; + + if (csiphy_dev->csiphy_info[index].csiphy_3phase) + is_3phase = true; + + if (csiphy_dev->combo_mode) { + /* for CPHY(3Phase) or DPHY(2Phase) combo mode selection */ + if (is_3phase) { + /* CPHY combo mode */ + if (csiphy_dev->ctrl_reg->csiphy_3ph_combo_reg) { + reg_array = csiphy_dev->ctrl_reg + ->csiphy_3ph_combo_reg; + } else { + CAM_WARN(CAM_CSIPHY, + "CPHY combo mode reg settings not found"); reg_array = csiphy_dev->ctrl_reg->csiphy_3ph_reg; - CAM_ERR(CAM_CSIPHY, - "Unsupported configuration, Falling back to CPHY mode"); } - } else - reg_array = - csiphy_dev->ctrl_reg->csiphy_3ph_reg; - csiphy_dev->num_irq_registers = 11; - cfg_size = - csiphy_dev->ctrl_reg->csiphy_reg.csiphy_3ph_config_array_size; - - lane_mask = csiphy_dev->csiphy_info.lane_mask & LANE_MASK_3PH; - mask = lane_mask; - while (mask != 0) { - temp = (i << 1)+1; - lane_enable |= ((mask & 0x1) << temp); - mask >>= 1; - i++; + cfg_size = csiphy_dev->ctrl_reg->csiphy_reg + .csiphy_3ph_config_array_size; + max_lanes = CAM_CSIPHY_MAX_CPHY_LANES; + } else { + /* DPHY combo mode*/ + if (csiphy_dev->ctrl_reg->csiphy_2ph_combo_mode_reg) { + reg_array = csiphy_dev + ->ctrl_reg->csiphy_2ph_combo_mode_reg; + } else { + CAM_WARN(CAM_CSIPHY, + "DPHY combo mode reg settings not found"); + reg_array = csiphy_dev + ->ctrl_reg->csiphy_2ph_reg; + } + cfg_size = csiphy_dev->ctrl_reg->csiphy_reg + .csiphy_2ph_config_array_size; + max_lanes = MAX_LANES; + } + } else if (csiphy_dev->cphy_dphy_combo_mode) { + /* for CPHY and DPHY combo mode selection */ + if (csiphy_dev->ctrl_reg->csiphy_2ph_3ph_mode_reg) { + reg_array = csiphy_dev + ->ctrl_reg->csiphy_2ph_3ph_mode_reg; + cfg_size = csiphy_dev->ctrl_reg->csiphy_reg + .csiphy_2ph_3ph_config_array_size; + max_lanes = CAM_CSIPHY_MAX_CPHY_DPHY_COMBO_LN; + } else { + reg_array = csiphy_dev->ctrl_reg->csiphy_3ph_reg; + cfg_size = + csiphy_dev->ctrl_reg->csiphy_reg + .csiphy_3ph_config_array_size; + CAM_WARN(CAM_CSIPHY, + "Unsupported configuration, Falling back to CPHY mission mode"); + max_lanes = CAM_CSIPHY_MAX_CPHY_LANES; + } + } else { + /* for CPHY(3Phase) or DPHY(2Phase) Non combe mode selection */ + if (is_3phase) { + CAM_DBG(CAM_CSIPHY, + "3phase Non combo mode reg array selected"); + reg_array = csiphy_dev->ctrl_reg->csiphy_3ph_reg; + max_lanes = CAM_CSIPHY_MAX_CPHY_LANES; + cfg_size = csiphy_dev->ctrl_reg->csiphy_reg + .csiphy_3ph_config_array_size; + } else { + CAM_DBG(CAM_CSIPHY, + "2PHASE Non combo mode reg array selected"); + reg_array = csiphy_dev->ctrl_reg->csiphy_2ph_reg; + cfg_size = csiphy_dev->ctrl_reg->csiphy_reg + .csiphy_2ph_config_array_size; + max_lanes = MAX_LANES; } } - size = csiphy_dev->ctrl_reg->csiphy_reg.csiphy_common_array_size; + lane_cnt = csiphy_dev->csiphy_info[index].lane_cnt; + lane_assign = csiphy_dev->csiphy_info[index].lane_assign; + lane_enable = csiphy_dev->csiphy_info[index].lane_enable; + size = csiphy_dev->ctrl_reg->csiphy_reg.csiphy_common_array_size; for (i = 0; i < size; i++) { csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_common_reg[i]; switch (csiphy_common_reg->csiphy_param_type) { case CSIPHY_LANE_ENABLE: + CAM_DBG(CAM_CSIPHY, "LANE_ENABLE: 0x%x", lane_enable); cam_io_w_mb(lane_enable, csiphybase + csiphy_common_reg->reg_addr); break; @@ -477,14 +608,14 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev) csiphybase + csiphy_common_reg->reg_addr); break; case CSIPHY_2PH_REGS: - if (!csiphy_dev->csiphy_info.csiphy_3phase) { + if (!is_3phase) { cam_io_w_mb(csiphy_common_reg->reg_data, csiphybase + csiphy_common_reg->reg_addr); } break; case CSIPHY_3PH_REGS: - if (csiphy_dev->csiphy_info.csiphy_3phase) { + if (is_3phase) { cam_io_w_mb(csiphy_common_reg->reg_data, csiphybase + csiphy_common_reg->reg_addr); @@ -498,23 +629,12 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev) csiphy_common_reg->delay + 5); } - while (lane_mask) { - if (!(lane_mask & 0x1)) { - lane_pos++; - lane_mask >>= 1; - continue; - } + intermediate_var = csiphy_dev->csiphy_info[index].settle_time; + do_div(intermediate_var, 200000000); + settle_cnt = intermediate_var; - intermediate_var = csiphy_dev->csiphy_info.settle_time; - do_div(intermediate_var, 200000000); - settle_cnt = intermediate_var; - if (csiphy_dev->csiphy_info.combo_mode == 1 && - (lane_pos >= 3)) { - intermediate_var = - csiphy_dev->csiphy_info.settle_time_combo_sensor; - do_div(intermediate_var, 200000000); - settle_cnt = intermediate_var; - } + for (lane_pos = 0; lane_pos < max_lanes; lane_pos++) { + CAM_DBG(CAM_CSIPHY, "lane_pos: %d is configuring", lane_pos); for (i = 0; i < cfg_size; i++) { switch (reg_array[lane_pos][i].csiphy_param_type) { case CSIPHY_LANE_ENABLE: @@ -546,15 +666,14 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev) reg_array[lane_pos][i].delay + 5); } } - lane_mask >>= 1; - lane_pos++; } - if (csiphy_dev->csiphy_info.csiphy_3phase) - cam_csiphy_cphy_data_rate_config(csiphy_dev); + if (csiphy_dev->csiphy_info[index].csiphy_3phase) + cam_csiphy_cphy_data_rate_config(csiphy_dev, index); cam_csiphy_cphy_irq_config(csiphy_dev); + CAM_DBG(CAM_CSIPHY, "EXIT"); return rc; } @@ -566,19 +685,31 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev) if (csiphy_dev->csiphy_state == CAM_CSIPHY_INIT) return; + if (!csiphy_dev->acquire_count) + return; + + if (csiphy_dev->acquire_count >= CSIPHY_MAX_INSTANCES_PER_PHY) { + CAM_WARN(CAM_CSIPHY, "acquire count is invalid: %u", + csiphy_dev->acquire_count); + csiphy_dev->acquire_count = + CSIPHY_MAX_INSTANCES_PER_PHY; + } + if (csiphy_dev->csiphy_state == CAM_CSIPHY_START) { soc_info = &csiphy_dev->soc_info; for (i = 0; i < csiphy_dev->acquire_count; i++) { - if (csiphy_dev->csiphy_info.secure_mode[i]) + if (csiphy_dev->csiphy_info[i].secure_mode) cam_csiphy_notify_secure_mode( csiphy_dev, CAM_SECURE_MODE_NON_SECURE, i); - csiphy_dev->csiphy_info.secure_mode[i] = + csiphy_dev->csiphy_info[i].secure_mode = CAM_SECURE_MODE_NON_SECURE; - csiphy_dev->csiphy_cpas_cp_reg_mask[i] = 0; + csiphy_dev->csiphy_info[i].csiphy_cpas_cp_reg_mask = 0; + csiphy_dev->csiphy_info[i].settle_time = 0; + csiphy_dev->csiphy_info[i].data_rate = 0; } cam_csiphy_reset(csiphy_dev); @@ -589,22 +720,18 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev) } if (csiphy_dev->csiphy_state == CAM_CSIPHY_ACQUIRE) { - if (csiphy_dev->bridge_intf.device_hdl[0] != -1) - cam_destroy_device_hdl( - csiphy_dev->bridge_intf.device_hdl[0]); - if (csiphy_dev->bridge_intf.device_hdl[1] != -1) - cam_destroy_device_hdl( - csiphy_dev->bridge_intf.device_hdl[1]); - csiphy_dev->bridge_intf.device_hdl[0] = -1; - csiphy_dev->bridge_intf.device_hdl[1] = -1; - csiphy_dev->bridge_intf.link_hdl[0] = -1; - csiphy_dev->bridge_intf.link_hdl[1] = -1; - csiphy_dev->bridge_intf.session_hdl[0] = -1; - csiphy_dev->bridge_intf.session_hdl[1] = -1; + for (i = 0; i < csiphy_dev->acquire_count; i++) { + if (csiphy_dev->csiphy_info[i].hdl_data.device_hdl + != -1) + cam_destroy_device_hdl( + csiphy_dev->csiphy_info[i] + .hdl_data.device_hdl); + csiphy_dev->csiphy_info[i].hdl_data.device_hdl = -1; + csiphy_dev->csiphy_info[i].hdl_data.session_hdl = -1; + } } csiphy_dev->ref_count = 0; - csiphy_dev->is_acquired_dev_combo_mode = 0; csiphy_dev->acquire_count = 0; csiphy_dev->start_dev_count = 0; csiphy_dev->csiphy_state = CAM_CSIPHY_INIT; @@ -615,6 +742,7 @@ static int32_t cam_csiphy_external_cmd(struct csiphy_device *csiphy_dev, { struct cam_csiphy_info cam_cmd_csiphy_info; int32_t rc = 0; + int32_t index = -1; if (copy_from_user(&cam_cmd_csiphy_info, u64_to_user_ptr(p_submit_cmd->packet_handle), @@ -622,37 +750,87 @@ static int32_t cam_csiphy_external_cmd(struct csiphy_device *csiphy_dev, CAM_ERR(CAM_CSIPHY, "failed to copy cam_csiphy_info\n"); rc = -EFAULT; } else { - csiphy_dev->csiphy_info.lane_cnt = + index = cam_csiphy_get_instance_offset(csiphy_dev, + p_submit_cmd->dev_handle); + if (index < 0 || + index >= csiphy_dev->session_max_device_support) { + CAM_ERR(CAM_CSIPHY, "index is invalid: %d", index); + return -EINVAL; + } + + csiphy_dev->csiphy_info[index].lane_cnt = cam_cmd_csiphy_info.lane_cnt; - csiphy_dev->csiphy_info.lane_cnt = - cam_cmd_csiphy_info.lane_cnt; - csiphy_dev->csiphy_info.lane_mask = - cam_cmd_csiphy_info.lane_mask; - csiphy_dev->csiphy_info.csiphy_3phase = - cam_cmd_csiphy_info.csiphy_3phase; - csiphy_dev->csiphy_info.combo_mode = - cam_cmd_csiphy_info.combo_mode; - csiphy_dev->csiphy_info.settle_time = + csiphy_dev->csiphy_info[index].lane_assign = + cam_cmd_csiphy_info.lane_assign; + csiphy_dev->csiphy_info[index].settle_time = cam_cmd_csiphy_info.settle_time; - csiphy_dev->csiphy_info.data_rate = + csiphy_dev->csiphy_info[index].data_rate = cam_cmd_csiphy_info.data_rate; CAM_DBG(CAM_CSIPHY, - "%s CONFIG_DEV_EXT settle_time= %lld lane_cnt=%d lane_mask=0x%x", + "%s CONFIG_DEV_EXT settle_time= %lld lane_cnt=%d", __func__, - csiphy_dev->csiphy_info.settle_time, - csiphy_dev->csiphy_info.lane_cnt, - csiphy_dev->csiphy_info.lane_mask); + csiphy_dev->csiphy_info[index].settle_time, + csiphy_dev->csiphy_info[index].lane_cnt); } return rc; } +static int cam_csiphy_update_lane( + struct csiphy_device *csiphy, int index, bool enable) +{ + int i = 0; + uint32_t lane_enable = 0; + uint32_t size = 0; + uint16_t lane_assign; + void __iomem *base_address; + struct csiphy_reg_t *csiphy_common_reg = NULL; + + base_address = csiphy->soc_info.reg_map[0].mem_base; + size = csiphy->ctrl_reg->csiphy_reg.csiphy_common_array_size; + + for (i = 0; i < size; i++) { + csiphy_common_reg = &csiphy->ctrl_reg->csiphy_common_reg[i]; + switch (csiphy_common_reg->csiphy_param_type) { + case CSIPHY_LANE_ENABLE: + CAM_DBG(CAM_CSIPHY, "LANE_ENABLE: %d", lane_enable); + lane_enable = cam_io_r(base_address + + csiphy_common_reg->reg_addr); + break; + } + } + + lane_assign = csiphy->csiphy_info[index].lane_assign; + + if (enable) + lane_enable |= csiphy->csiphy_info[index].lane_enable; + else + lane_enable &= ~csiphy->csiphy_info[index].lane_enable; + + CAM_DBG(CAM_CSIPHY, "lane_assign: 0x%x, lane_enable: 0x%x", + lane_assign, lane_enable); + for (i = 0; i < size; i++) { + csiphy_common_reg = &csiphy->ctrl_reg->csiphy_common_reg[i]; + switch (csiphy_common_reg->csiphy_param_type) { + case CSIPHY_LANE_ENABLE: + CAM_DBG(CAM_CSIPHY, "LANE_ENABLE: %d", lane_enable); + cam_io_w_mb(lane_enable, + base_address + csiphy_common_reg->reg_addr); + if (csiphy_common_reg->delay) + usleep_range(csiphy_common_reg->delay, + csiphy_common_reg->delay + 5); + break; + } + } + + return 0; +} + int32_t cam_csiphy_core_cfg(void *phy_dev, void *arg) { struct csiphy_device *csiphy_dev = (struct csiphy_device *)phy_dev; - struct csiphy_intf_params *bridge_intf = NULL; struct cam_control *cmd = (struct cam_control *)arg; int32_t rc = 0; @@ -673,13 +851,28 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, case CAM_ACQUIRE_DEV: { struct cam_sensor_acquire_dev csiphy_acq_dev; struct cam_csiphy_acquire_dev_info csiphy_acq_params; - + int index; struct cam_create_dev_hdl bridge_params; - if (csiphy_dev->csiphy_state == CAM_CSIPHY_START) { + CAM_DBG(CAM_CSIPHY, "ACQUIRE_CNT: %d COMBO_MODE: %d", + csiphy_dev->acquire_count, + csiphy_dev->combo_mode); + if ((csiphy_dev->csiphy_state == CAM_CSIPHY_START) && + (csiphy_dev->combo_mode == 0) && + (csiphy_dev->acquire_count > 0)) { CAM_ERR(CAM_CSIPHY, - "Not in right state to acquire : %d", - csiphy_dev->csiphy_state); + "NonComboMode does not support multiple acquire: Acquire_count: %d", + csiphy_dev->acquire_count); + rc = -EINVAL; + goto release_mutex; + } + + if ((csiphy_dev->acquire_count) && + (csiphy_dev->acquire_count >= + csiphy_dev->session_max_device_support)) { + CAM_ERR(CAM_CSIPHY, + "Max acquires are allowed in combo mode: %d", + csiphy_dev->session_max_device_support); rc = -EINVAL; goto release_mutex; } @@ -702,32 +895,37 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, goto release_mutex; } - if (csiphy_dev->acquire_count == 2) { + if (csiphy_acq_params.combo_mode && + csiphy_acq_params.cphy_dphy_combo_mode) { CAM_ERR(CAM_CSIPHY, - "CSIPHY device do not allow more than 2 acquires"); + "Cannot support both Combo_mode and cphy_dphy_combo_mode"); rc = -EINVAL; goto release_mutex; } - if ((csiphy_acq_params.combo_mode == 1) && - (csiphy_dev->is_acquired_dev_combo_mode == 1)) { - CAM_ERR(CAM_CSIPHY, - "Multiple Combo Acq are not allowed: cm: %d, acm: %d", - csiphy_acq_params.combo_mode, - csiphy_dev->is_acquired_dev_combo_mode); - rc = -EINVAL; - goto release_mutex; + if (csiphy_acq_params.combo_mode == 1) { + CAM_DBG(CAM_CSIPHY, "combo mode stream detected"); + csiphy_dev->combo_mode = 1; + if (csiphy_acq_params.csiphy_3phase) + csiphy_dev->session_max_device_support = + CSIPHY_MAX_INSTANCES_PER_PHY; + else + csiphy_dev->session_max_device_support = + CSIPHY_MAX_INSTANCES_PER_PHY - 1; } - if ((csiphy_acq_params.combo_mode != 1) && - (csiphy_dev->is_acquired_dev_combo_mode != 1) && - (csiphy_dev->acquire_count == 1)) { - CAM_ERR(CAM_CSIPHY, - "Multiple Acquires are not allowed cm: %d acm: %d", - csiphy_acq_params.combo_mode, - csiphy_dev->is_acquired_dev_combo_mode); - rc = -EINVAL; - goto release_mutex; + if (csiphy_acq_params.cphy_dphy_combo_mode == 1) { + CAM_DBG(CAM_CSIPHY, + "cphy_dphy_combo_mode stream detected"); + csiphy_dev->cphy_dphy_combo_mode = 1; + csiphy_dev->session_max_device_support = + CSIPHY_MAX_INSTANCES_PER_PHY - 1; + } + + if (!csiphy_acq_params.combo_mode && + !csiphy_acq_params.cphy_dphy_combo_mode) { + CAM_DBG(CAM_CSIPHY, "Non Combo Mode stream"); + csiphy_dev->session_max_device_support = 1; } bridge_params.ops = NULL; @@ -735,22 +933,19 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, bridge_params.v4l2_sub_dev_flag = 0; bridge_params.media_entity_flag = 0; bridge_params.priv = csiphy_dev; - - if (csiphy_acq_params.combo_mode >= 2) { - CAM_ERR(CAM_CSIPHY, "Invalid combo_mode %d", - csiphy_acq_params.combo_mode); - rc = -EINVAL; - goto release_mutex; - } - + index = csiphy_dev->acquire_count; csiphy_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); - bridge_intf = &csiphy_dev->bridge_intf; - bridge_intf->device_hdl[csiphy_acq_params.combo_mode] - = csiphy_acq_dev.device_handle; - bridge_intf->session_hdl[csiphy_acq_params.combo_mode] = + csiphy_dev->csiphy_info[index].hdl_data.device_hdl = + csiphy_acq_dev.device_handle; + csiphy_dev->csiphy_info[index].hdl_data.session_hdl = csiphy_acq_dev.session_handle; + csiphy_dev->csiphy_info[index].csiphy_3phase = + csiphy_acq_params.csiphy_3phase; + CAM_DBG(CAM_CSIPHY, "Add dev_handle:0x%x at index: %d ", + csiphy_dev->csiphy_info[index].hdl_data.device_hdl, + index); if (copy_to_user(u64_to_user_ptr(cmd->handle), &csiphy_acq_dev, sizeof(struct cam_sensor_acquire_dev))) { @@ -758,11 +953,12 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, rc = -EINVAL; goto release_mutex; } - if (csiphy_acq_params.combo_mode == 1) - csiphy_dev->is_acquired_dev_combo_mode = 1; csiphy_dev->acquire_count++; - csiphy_dev->csiphy_state = CAM_CSIPHY_ACQUIRE; + CAM_DBG(CAM_CSIPHY, "ACQUIRE_CNT: %d", + csiphy_dev->acquire_count); + if (csiphy_dev->csiphy_state == CAM_CSIPHY_INIT) + csiphy_dev->csiphy_state = CAM_CSIPHY_ACQUIRE; } break; case CAM_QUERY_CAP: { @@ -788,8 +984,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, goto release_mutex; } - if ((csiphy_dev->csiphy_state != CAM_CSIPHY_START) || - !csiphy_dev->start_dev_count) { + if (csiphy_dev->csiphy_state != CAM_CSIPHY_START) { CAM_ERR(CAM_CSIPHY, "Not in right state to stop : %d", csiphy_dev->csiphy_state); goto release_mutex; @@ -797,35 +992,44 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, offset = cam_csiphy_get_instance_offset(csiphy_dev, config.dev_handle); - if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) { - CAM_ERR(CAM_CSIPHY, "Invalid offset"); + if (offset < 0 || + offset >= csiphy_dev->session_max_device_support) { + CAM_ERR(CAM_CSIPHY, "Index is invalid: %d", offset); goto release_mutex; } + CAM_INFO(CAM_CSIPHY, + "STOP_DEV: CSIPHY_IDX: %d, Device_slot: %d, Datarate: %llu, Settletime: %llu", + csiphy_dev->soc_info.index, offset, + csiphy_dev->csiphy_info[offset].data_rate, + csiphy_dev->csiphy_info[offset].settle_time); + if (--csiphy_dev->start_dev_count) { CAM_DBG(CAM_CSIPHY, "Stop Dev ref Cnt: %d", csiphy_dev->start_dev_count); - if (csiphy_dev->csiphy_info.secure_mode[offset]) + if (csiphy_dev->csiphy_info[offset].secure_mode) cam_csiphy_notify_secure_mode( csiphy_dev, CAM_SECURE_MODE_NON_SECURE, offset); - csiphy_dev->csiphy_info.secure_mode[offset] = + csiphy_dev->csiphy_info[offset].secure_mode = CAM_SECURE_MODE_NON_SECURE; - csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0; + csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask + = 0; + cam_csiphy_update_lane(csiphy_dev, offset, false); goto release_mutex; } - if (csiphy_dev->csiphy_info.secure_mode[offset]) + if (csiphy_dev->csiphy_info[offset].secure_mode) cam_csiphy_notify_secure_mode( csiphy_dev, CAM_SECURE_MODE_NON_SECURE, offset); - csiphy_dev->csiphy_info.secure_mode[offset] = + csiphy_dev->csiphy_info[offset].secure_mode = CAM_SECURE_MODE_NON_SECURE; - csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0x0; + csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask = 0x0; rc = cam_csiphy_disable_hw(csiphy_dev); if (rc < 0) @@ -835,6 +1039,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, if (rc < 0) CAM_ERR(CAM_CSIPHY, "de-voting CPAS: %d", rc); + CAM_DBG(CAM_CSIPHY, "All PHY devices stopped"); csiphy_dev->csiphy_state = CAM_CSIPHY_ACQUIRE; } break; @@ -857,17 +1062,18 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, offset = cam_csiphy_get_instance_offset(csiphy_dev, release.dev_handle); - if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) { - CAM_ERR(CAM_CSIPHY, "Invalid offset"); + if (offset < 0 || + offset >= csiphy_dev->session_max_device_support) { + CAM_ERR(CAM_CSIPHY, "index is invalid: %d", offset); goto release_mutex; } - if (csiphy_dev->csiphy_info.secure_mode[offset]) + if (csiphy_dev->csiphy_info[offset].secure_mode) cam_csiphy_notify_secure_mode( csiphy_dev, CAM_SECURE_MODE_NON_SECURE, offset); - csiphy_dev->csiphy_info.secure_mode[offset] = + csiphy_dev->csiphy_info[offset].secure_mode = CAM_SECURE_MODE_NON_SECURE; csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0x0; @@ -875,32 +1081,29 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, rc = cam_destroy_device_hdl(release.dev_handle); if (rc < 0) CAM_ERR(CAM_CSIPHY, "destroying the device hdl"); - if (release.dev_handle == - csiphy_dev->bridge_intf.device_hdl[0]) { - csiphy_dev->bridge_intf.device_hdl[0] = -1; - csiphy_dev->bridge_intf.link_hdl[0] = -1; - csiphy_dev->bridge_intf.session_hdl[0] = -1; - } else { - csiphy_dev->bridge_intf.device_hdl[1] = -1; - csiphy_dev->bridge_intf.link_hdl[1] = -1; - csiphy_dev->bridge_intf.session_hdl[1] = -1; - csiphy_dev->is_acquired_dev_combo_mode = 0; - } + csiphy_dev->csiphy_info[offset].hdl_data.device_hdl = -1; + csiphy_dev->csiphy_info[offset].hdl_data.session_hdl = -1; csiphy_dev->config_count--; - csiphy_dev->acquire_count--; + if (csiphy_dev->acquire_count) { + csiphy_dev->acquire_count--; + CAM_DBG(CAM_CSIPHY, "Acquire_cnt: %d", + csiphy_dev->acquire_count); + } - if (csiphy_dev->acquire_count == 0) + if (csiphy_dev->start_dev_count == 0) { + CAM_DBG(CAM_CSIPHY, "All PHY devices released"); csiphy_dev->csiphy_state = CAM_CSIPHY_INIT; - + } if (csiphy_dev->config_count == 0) { CAM_DBG(CAM_CSIPHY, "reset csiphy_info"); - csiphy_dev->csiphy_info.lane_mask = 0; - csiphy_dev->csiphy_info.lane_cnt = 0; - csiphy_dev->csiphy_info.combo_mode = 0; + csiphy_dev->csiphy_info[offset].lane_cnt = 0; + csiphy_dev->csiphy_info[offset].lane_assign = 0; + csiphy_dev->csiphy_info[offset].csiphy_3phase = -1; + csiphy_dev->combo_mode = 0; } - } break; + } case CAM_CONFIG_DEV: { struct cam_config_dev_cmd config; @@ -922,6 +1125,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, struct cam_axi_vote axi_vote = {0}; struct cam_start_stop_dev_cmd config; int32_t offset; + int clk_vote_level = -1; rc = copy_from_user(&config, (void __user *)cmd->handle, sizeof(config)); @@ -930,18 +1134,86 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, goto release_mutex; } - if (csiphy_dev->csiphy_state == CAM_CSIPHY_START) { - csiphy_dev->start_dev_count++; + if ((csiphy_dev->csiphy_state == CAM_CSIPHY_START) && + (csiphy_dev->start_dev_count > + csiphy_dev->session_max_device_support)) { + CAM_ERR(CAM_CSIPHY, + "Invalid start count: %d, Max supported devices: %u", + csiphy_dev->start_dev_count, + csiphy_dev->session_max_device_support); + rc = -EINVAL; goto release_mutex; } offset = cam_csiphy_get_instance_offset(csiphy_dev, config.dev_handle); - if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) { - CAM_ERR(CAM_CSIPHY, "Invalid offset"); + if (offset < 0 || + offset >= csiphy_dev->session_max_device_support) { + CAM_ERR(CAM_CSIPHY, "index is invalid: %d", offset); goto release_mutex; } + CAM_INFO(CAM_CSIPHY, + "START_DEV: CSIPHY_IDX: %d, Device_slot: %d, Datarate: %llu, Settletime: %llu", + csiphy_dev->soc_info.index, offset, + csiphy_dev->csiphy_info[offset].data_rate, + csiphy_dev->csiphy_info[offset].settle_time); + + if (csiphy_dev->start_dev_count) { + clk_vote_level = + csiphy_dev->ctrl_reg->getclockvoting( + csiphy_dev, offset); + rc = cam_soc_util_set_clk_rate_level( + &csiphy_dev->soc_info, clk_vote_level); + if (rc) { + CAM_WARN(CAM_CSIPHY, + "Failed to set the clk_rate level: %d", + clk_vote_level); + rc = 0; + } + + if (csiphy_dev->csiphy_info[offset].secure_mode == 1) { + if (cam_cpas_is_feature_supported( + CAM_CPAS_SECURE_CAMERA_ENABLE) != 1) { + CAM_WARN(CAM_CSIPHY, + "sec_cam: camera fuse bit not set"); + rc = 0; + goto release_mutex; + } + + rc = cam_csiphy_notify_secure_mode(csiphy_dev, + CAM_SECURE_MODE_SECURE, offset); + if (rc < 0) { + csiphy_dev->csiphy_info[offset] + .secure_mode = + CAM_SECURE_MODE_NON_SECURE; + CAM_WARN(CAM_CSIPHY, + "sec_cam: notify failed: rc: %d", + rc); + rc = 0; + goto release_mutex; + } + } + if (csiphy_dev->csiphy_info[offset].csiphy_3phase) + cam_csiphy_cphy_data_rate_config( + csiphy_dev, offset); + + rc = cam_csiphy_update_lane(csiphy_dev, offset, true); + if (csiphy_dump == 1) + cam_csiphy_mem_dmp(&csiphy_dev->soc_info); + if (rc) { + CAM_WARN(CAM_CSIPHY, + "csiphy_config_dev failed"); + goto release_mutex; + } + + csiphy_dev->start_dev_count++; + goto release_mutex; + } + + CAM_DBG(CAM_CSIPHY, "Start_dev_cnt: %d", + csiphy_dev->start_dev_count); + ahb_vote.type = CAM_VOTE_ABSOLUTE; ahb_vote.vote.level = CAM_LOWSVS_VOTE; axi_vote.num_paths = 1; @@ -958,7 +1230,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, goto release_mutex; } - if (csiphy_dev->csiphy_info.secure_mode[offset] == 1) { + if (csiphy_dev->csiphy_info[offset].secure_mode == 1) { if (cam_cpas_is_feature_supported( CAM_CPAS_SECURE_CAMERA_ENABLE) != 1) { CAM_ERR(CAM_CSIPHY, @@ -972,20 +1244,20 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, csiphy_dev, CAM_SECURE_MODE_SECURE, offset); if (rc < 0) { - csiphy_dev->csiphy_info.secure_mode[offset] = + csiphy_dev->csiphy_info[offset].secure_mode = CAM_SECURE_MODE_NON_SECURE; cam_cpas_stop(csiphy_dev->cpas_handle); goto release_mutex; } } - rc = cam_csiphy_enable_hw(csiphy_dev); + rc = cam_csiphy_enable_hw(csiphy_dev, offset); if (rc != 0) { CAM_ERR(CAM_CSIPHY, "cam_csiphy_enable_hw failed"); cam_cpas_stop(csiphy_dev->cpas_handle); goto release_mutex; } - rc = cam_csiphy_config_dev(csiphy_dev); + rc = cam_csiphy_config_dev(csiphy_dev, config.dev_handle); if (csiphy_dump == 1) cam_csiphy_mem_dmp(&csiphy_dev->soc_info); @@ -996,6 +1268,8 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, goto release_mutex; } csiphy_dev->start_dev_count++; + CAM_DBG(CAM_CSIPHY, "START DEV CNT: %d", + csiphy_dev->start_dev_count); csiphy_dev->csiphy_state = CAM_CSIPHY_START; } break; diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c index ebfd041d13..9150125fe5 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c @@ -131,6 +131,7 @@ static int cam_csiphy_component_bind(struct device *dev, struct csiphy_device *new_csiphy_dev; int32_t rc = 0; struct platform_device *pdev = to_platform_device(dev); + int i; new_csiphy_dev = devm_kzalloc(&pdev->dev, sizeof(struct csiphy_device), GFP_KERNEL); @@ -183,18 +184,23 @@ static int cam_csiphy_component_bind(struct device *dev, platform_set_drvdata(pdev, &(new_csiphy_dev->v4l2_dev_str.sd)); - new_csiphy_dev->bridge_intf.device_hdl[0] = -1; - new_csiphy_dev->bridge_intf.device_hdl[1] = -1; - new_csiphy_dev->bridge_intf.ops.get_dev_info = - NULL; - new_csiphy_dev->bridge_intf.ops.link_setup = - NULL; - new_csiphy_dev->bridge_intf.ops.apply_req = - NULL; + for (i = 0; i < CSIPHY_MAX_INSTANCES_PER_PHY; i++) { + new_csiphy_dev->csiphy_info[i].hdl_data.device_hdl = -1; + new_csiphy_dev->csiphy_info[i].hdl_data.session_hdl = -1; + new_csiphy_dev->csiphy_info[i].csiphy_3phase = -1; + new_csiphy_dev->csiphy_info[i].data_rate = 0; + new_csiphy_dev->csiphy_info[i].settle_time = 0; + new_csiphy_dev->csiphy_info[i].lane_cnt = 0; + new_csiphy_dev->csiphy_info[i].lane_assign = 0; + new_csiphy_dev->csiphy_info[i].lane_enable = 0; + } + + new_csiphy_dev->ops.get_dev_info = NULL; + new_csiphy_dev->ops.link_setup = NULL; + new_csiphy_dev->ops.apply_req = NULL; new_csiphy_dev->acquire_count = 0; new_csiphy_dev->start_dev_count = 0; - new_csiphy_dev->is_acquired_dev_combo_mode = 0; cpas_parms.cam_cpas_client_cb = NULL; cpas_parms.cell_index = new_csiphy_dev->soc_info.index; diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h index ac5a017b15..35c2f585de 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h @@ -29,7 +29,7 @@ #include "cam_context.h" #define MAX_CSIPHY 6 -#define MAX_DPHY_DATA_LN 4 + #define MAX_LRME_V4l2_EVENTS 30 #define CSIPHY_NUM_CLK_MAX 16 #define MAX_CSIPHY_REG_ARRAY 70 @@ -41,6 +41,7 @@ #define MAX_DATA_RATE_REGS 30 #define CAMX_CSIPHY_DEV_NAME "cam-csiphy-driver" +#define CAM_CSIPHY_RX_CLK_SRC "cphy_rx_src_clk" #define CSIPHY_POWER_UP 0 #define CSIPHY_POWER_DOWN 1 @@ -53,20 +54,25 @@ #define CSIPHY_2PH_REGS 5 #define CSIPHY_3PH_REGS 6 -#define CSIPHY_MAX_INSTANCES 2 +#define CSIPHY_MAX_INSTANCES_PER_PHY 3 #define CAM_CSIPHY_MAX_DPHY_LANES 4 #define CAM_CSIPHY_MAX_CPHY_LANES 3 +#define CAM_CSIPHY_MAX_CPHY_DPHY_COMBO_LN 3 +#define CAM_CSIPHY_MAX_CPHY_COMBO_LN 3 + + +#define DPHY_LANE_0 BIT(0) +#define CPHY_LANE_0 BIT(1) +#define DPHY_LANE_1 BIT(2) +#define CPHY_LANE_1 BIT(3) +#define DPHY_LANE_2 BIT(4) +#define CPHY_LANE_2 BIT(5) +#define DPHY_LANE_3 BIT(6) +#define DPHY_CLK_LN BIT(7) #define ENABLE_IRQ false -#undef CDBG -#ifdef CAM_CSIPHY_CORE_DEBUG -#define CDBG(fmt, args...) pr_err(fmt, ##args) -#else -#define CDBG(fmt, args...) pr_debug(fmt, ##args) -#endif - enum cam_csiphy_state { CAM_CSIPHY_INIT, CAM_CSIPHY_ACQUIRE, @@ -111,6 +117,7 @@ struct csiphy_reg_parms_t { uint32_t csiphy_reset_array_size; uint32_t csiphy_2ph_config_array_size; uint32_t csiphy_3ph_config_array_size; + uint32_t csiphy_2ph_3ph_config_array_size; uint32_t csiphy_cpas_cp_bits_per_phy; uint32_t csiphy_cpas_cp_is_interleaved; uint32_t csiphy_cpas_cp_2ph_offset; @@ -123,22 +130,17 @@ struct csiphy_reg_parms_t { * struct csiphy_intf_params * @device_hdl: Device Handle * @session_hdl: Session Handle - * @ops: KMD operations - * @crm_cb: Callback API pointers */ -struct csiphy_intf_params { - int32_t device_hdl[CSIPHY_MAX_INSTANCES]; - int32_t session_hdl[CSIPHY_MAX_INSTANCES]; - int32_t link_hdl[CSIPHY_MAX_INSTANCES]; - struct cam_req_mgr_kmd_ops ops; - struct cam_req_mgr_crm_cb *crm_cb; +struct csiphy_hdl_tbl { + int32_t device_hdl; + int32_t session_hdl; }; /** * struct csiphy_reg_t - * @reg_addr: Register address - * @reg_data: Register data - * @delay: Delay in us + * @reg_addr: Register address + * @reg_data: Register data + * @delay: Delay in us * @csiphy_param_type: CSIPhy parameter type */ struct csiphy_reg_t { @@ -200,38 +202,35 @@ struct csiphy_ctrl_t { struct csiphy_reg_t (*csiphy_2ph_reg)[MAX_SETTINGS_PER_LANE]; struct csiphy_reg_t (*csiphy_2ph_combo_mode_reg)[MAX_SETTINGS_PER_LANE]; struct csiphy_reg_t (*csiphy_3ph_reg)[MAX_SETTINGS_PER_LANE]; + struct csiphy_reg_t (*csiphy_3ph_combo_reg)[MAX_SETTINGS_PER_LANE]; struct csiphy_reg_t (*csiphy_2ph_3ph_mode_reg)[MAX_SETTINGS_PER_LANE]; - enum cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev); + enum cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev, + int32_t index); struct data_rate_settings_t *data_rates_settings_table; }; /** - * cam_csiphy_param: Provides cmdbuffer structre - * @lane_mask : Lane mask details - * @lane_assign : Lane sensor will be using - * @csiphy_3phase : Mentions DPHY or CPHY - * @combo_mode : Info regarding combo_mode is enable / disable - * @lane_cnt : Total number of lanes - * @reserved - * @3phase : Details whether 3Phase / 2Phase operation - * @settle_time : Settling time in ms - * @settle_time_combo_sensor : Settling time in ms - * @data_rate : Data rate in mbps - * @data_rate_combo_sensor: data rate of combo sensor - * in the the same phy - * + * cam_csiphy_param : Provides cmdbuffer structure + * @lane_assign : Lane sensor will be using + * @lane_cnt : Total number of lanes + * @secure_mode : To identify whether stream is secure/nonsecure + * @lane_enable : Data Lane selection + * @settle_time : Settling time in ms + * @data_rate : Data rate in mbps + * @csiphy_3phase : To identify DPHY or CPHY + * @csiphy_cpas_cp_reg_mask : CP reg mask for phy instance + * @hdl_data : CSIPHY handle table */ struct cam_csiphy_param { - uint16_t lane_mask; - uint16_t lane_assign; - uint8_t csiphy_3phase; - uint8_t combo_mode; - uint8_t lane_cnt; - uint8_t secure_mode[CSIPHY_MAX_INSTANCES]; - uint64_t settle_time; - uint64_t settle_time_combo_sensor; - uint64_t data_rate; - uint64_t data_rate_combo_sensor; + uint16_t lane_assign; + uint8_t lane_cnt; + uint8_t secure_mode; + uint32_t lane_enable; + uint64_t settle_time; + uint64_t data_rate; + int csiphy_3phase; + uint64_t csiphy_cpas_cp_reg_mask; + struct csiphy_hdl_tbl hdl_data; }; /** @@ -255,41 +254,50 @@ struct cam_csiphy_param { * @csi_3phase: Is it a 3Phase mode * @ref_count: Reference count * @clk_lane: Clock lane + * @rx_clk_src_idx: Phy src clk index * @acquire_count: Acquire device count * @start_dev_count: Start count - * @is_acquired_dev_combo_mode: Flag that mentions whether already acquired - * device is for combo mode * @soc_info: SOC information * @cpas_handle: CPAS handle * @config_count: Config reg count - * @csiphy_cpas_cp_reg_mask: CP reg mask for phy instance + * @current_data_rate: Data rate in mbps + * @csiphy_3phase: To identify DPHY or CPHY at top level + * @combo_mode: Info regarding combo_mode is enable / disable + * @ops: KMD operations + * @crm_cb: Callback API pointers */ struct csiphy_device { - char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; - struct mutex mutex; - uint32_t hw_version; - enum cam_csiphy_state csiphy_state; - struct csiphy_ctrl_t *ctrl_reg; - uint32_t csiphy_max_clk; - struct msm_cam_clk_info csiphy_3p_clk_info[2]; - struct clk *csiphy_3p_clk[2]; - unsigned char csi_3phase; - int32_t ref_count; - uint16_t lane_mask[MAX_CSIPHY]; - uint8_t is_csiphy_3phase_hw; - uint8_t is_divisor_32_comp; - uint8_t num_irq_registers; - struct cam_subdev v4l2_dev_str; - struct cam_csiphy_param csiphy_info; - struct csiphy_intf_params bridge_intf; - uint32_t clk_lane; - uint32_t acquire_count; - uint32_t start_dev_count; - uint32_t is_acquired_dev_combo_mode; - struct cam_hw_soc_info soc_info; - uint32_t cpas_handle; - uint32_t config_count; - uint64_t csiphy_cpas_cp_reg_mask[CSIPHY_MAX_INSTANCES]; + char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH]; + struct mutex mutex; + uint32_t hw_version; + enum cam_csiphy_state csiphy_state; + struct csiphy_ctrl_t *ctrl_reg; + uint32_t csiphy_max_clk; + struct msm_cam_clk_info csiphy_3p_clk_info[2]; + struct clk *csiphy_3p_clk[2]; + int32_t ref_count; + uint16_t lane_mask[MAX_CSIPHY]; + uint8_t is_csiphy_3phase_hw; + uint8_t is_divisor_32_comp; + uint8_t num_irq_registers; + struct cam_subdev v4l2_dev_str; + struct cam_csiphy_param csiphy_info[ + CSIPHY_MAX_INSTANCES_PER_PHY]; + uint32_t clk_lane; + uint8_t rx_clk_src_idx; + uint32_t acquire_count; + uint32_t start_dev_count; + struct cam_hw_soc_info soc_info; + uint32_t cpas_handle; + uint32_t config_count; + uint64_t current_data_rate; + uint64_t csiphy_cpas_cp_reg_mask[ + CSIPHY_MAX_INSTANCES_PER_PHY]; + uint8_t session_max_device_support; + uint8_t combo_mode; + uint8_t cphy_dphy_combo_mode; + struct cam_req_mgr_kmd_ops ops; + struct cam_req_mgr_crm_cb *crm_cb; }; /** diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c index bedd0570b4..5143f2ab0a 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c @@ -126,26 +126,25 @@ int32_t cam_csiphy_status_dmp(struct csiphy_device *csiphy_dev) -enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev) +enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev, + int32_t index) { CAM_DBG(CAM_CSIPHY, "voting for SVS"); return CAM_SVS_VOTE; } -enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev) +enum cam_vote_level get_clk_voting_dynamic( + struct csiphy_device *csiphy_dev, int32_t index) { uint32_t cam_vote_level = 0; uint32_t last_valid_vote = 0; struct cam_hw_soc_info *soc_info; - uint64_t phy_data_rate = csiphy_dev->csiphy_info.data_rate; + uint64_t phy_data_rate = csiphy_dev->csiphy_info[index].data_rate; soc_info = &csiphy_dev->soc_info; + phy_data_rate = max(phy_data_rate, csiphy_dev->current_data_rate); - if (csiphy_dev->is_acquired_dev_combo_mode) - phy_data_rate = max(phy_data_rate, - csiphy_dev->csiphy_info.data_rate_combo_sensor); - - if (csiphy_dev->csiphy_info.csiphy_3phase) { + if (csiphy_dev->csiphy_info[index].csiphy_3phase) { if (csiphy_dev->is_divisor_32_comp) do_div(phy_data_rate, CSIPHY_DIVISOR_32); else @@ -156,19 +155,21 @@ enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev) /* round off to next integer */ phy_data_rate += 1; + csiphy_dev->current_data_rate = phy_data_rate; for (cam_vote_level = 0; cam_vote_level < CAM_MAX_VOTE; cam_vote_level++) { if (soc_info->clk_level_valid[cam_vote_level] != true) continue; - if (soc_info->clk_rate[cam_vote_level][0] > - phy_data_rate) { + if (soc_info->clk_rate[cam_vote_level] + [csiphy_dev->rx_clk_src_idx] > phy_data_rate) { CAM_DBG(CAM_CSIPHY, "match detected %s : %llu:%d level : %d", - soc_info->clk_name[0], + soc_info->clk_name[csiphy_dev->rx_clk_src_idx], phy_data_rate, - soc_info->clk_rate[cam_vote_level][0], + soc_info->clk_rate[cam_vote_level] + [csiphy_dev->rx_clk_src_idx], cam_vote_level); return cam_vote_level; } @@ -177,7 +178,7 @@ enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev) return last_valid_vote; } -int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev) +int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev, int32_t index) { int32_t rc = 0; struct cam_hw_soc_info *soc_info; @@ -191,7 +192,7 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev) return rc; } - vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev); + vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev, index); rc = cam_soc_util_enable_platform_resource(soc_info, true, vote_level, ENABLE_IRQ); if (rc < 0) { @@ -466,6 +467,10 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev, csiphy_dev->csiphy_3p_clk[1] = soc_info->clk[i]; continue; + } else if (!strcmp(soc_info->clk_name[i], + CAM_CSIPHY_RX_CLK_SRC)) { + csiphy_dev->rx_clk_src_idx = i; + continue; } CAM_DBG(CAM_CSIPHY, "clk_rate[%d] = %d", clk_cnt, diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h index 0416d8cda6..2ae08006fa 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h +++ b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h @@ -21,9 +21,6 @@ #include "cam_csiphy_dev.h" #include "cam_csiphy_core.h" -#undef CDBG -#define CDBG(fmt, args...) pr_debug(fmt, ##args) - #define CSI_3PHASE_HW 1 #define CSIPHY_VERSION_V35 0x35 #define CSIPHY_VERSION_V10 0x10 @@ -55,7 +52,7 @@ int cam_csiphy_parse_dt_info(struct platform_device *pdev, * * This API enables SOC related parameters */ -int cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev); +int cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev, int32_t index); /** * @csiphy_dev: CSIPhy device structure diff --git a/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h b/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h index a9290d6e6c..bddd49432d 100644 --- a/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h +++ b/drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h @@ -16,6 +16,7 @@ struct csiphy_reg_parms_t csiphy_v1_2_3 = { .csiphy_reset_array_size = 5, .csiphy_2ph_config_array_size = 16, .csiphy_3ph_config_array_size = 28, + .csiphy_2ph_3ph_config_array_size = 0, .csiphy_2ph_clock_lane = 0x1, .csiphy_2ph_combo_ck_ln = 0x10, }; diff --git a/drivers/cam_utils/cam_compat.c b/drivers/cam_utils/cam_compat.c index 27c84b0eca..21ebc95ab3 100644 --- a/drivers/cam_utils/cam_compat.c +++ b/drivers/cam_utils/cam_compat.c @@ -77,11 +77,12 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, { int rc = 0; - if (offset >= CSIPHY_MAX_INSTANCES) { + if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) { CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset"); rc = -EINVAL; } else if (qcom_scm_camera_protect_phy_lanes(protect, - csiphy_dev->csiphy_cpas_cp_reg_mask[offset])) { + csiphy_dev->csiphy_info[offset] + .csiphy_cpas_cp_reg_mask)) { CAM_ERR(CAM_CSIPHY, "SCM call to hypervisor failed"); rc = -EINVAL; } @@ -158,10 +159,11 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev, struct scm_desc description = { .arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL), .args[0] = protect, - .args[1] = csiphy_dev->csiphy_cpas_cp_reg_mask[offset], + .args[1] = csiphy_dev->csiphy_info[offset] + .csiphy_cpas_cp_reg_mask, }; - if (offset >= CSIPHY_MAX_INSTANCES) { + if (offset >= CSIPHY_MAX_INSTANCES_PER_PHY) { CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset"); rc = -EINVAL; } else if (scm_call2(SCM_SIP_FNID(0x18, 0x7), &description)) { diff --git a/include/uapi/camera/media/cam_sensor.h b/include/uapi/camera/media/cam_sensor.h index bc9498ea61..4ff9ecc7c3 100644 --- a/include/uapi/camera/media/cam_sensor.h +++ b/include/uapi/camera/media/cam_sensor.h @@ -324,23 +324,18 @@ struct cam_cmd_unconditional_wait { } __attribute__((packed)); /** - * cam_csiphy_info: Provides cmdbuffer structre - * @lane_mask : Lane mask details - * @lane_assign : Lane sensor will be using - * @csiphy_3phase : Total number of lanes - * @combo_mode : Info regarding combo_mode is enable / disable - * @lane_cnt : Total number of lanes - * @secure_mode : Secure mode flag to enable / disable - * @3phase : Details whether 3Phase / 2Phase operation - * @settle_time : Settling time in ms - * @data_rate : Data rate + * cam_csiphy_info : Provides cmdbuffer structre + * @lane_assign : Lane sensor will be using + * @lane_cnt : Total number of lanes + * @secure_mode : Secure mode flag to enable / disable + * @settle_time : Settling time in ms + * @data_rate : Data rate * */ struct cam_csiphy_info { - __u16 lane_mask; + __u16 reserved; __u16 lane_assign; - __u8 csiphy_3phase; - __u8 combo_mode; + __u16 reserved1; __u8 lane_cnt; __u8 secure_mode; __u64 settle_time; @@ -349,14 +344,18 @@ struct cam_csiphy_info { /** * cam_csiphy_acquire_dev_info : Information needed for - * csiphy at the time of acquire - * @combo_mode : Indicates the device mode of operation - * @reserved + * csiphy at the time of acquire + * @combo_mode : Indicates the device mode of operation + * @cphy_dphy_combo_mode : Info regarding cphy_dphy_combo mode + * @csiphy_3phase : Details whether 3Phase / 2Phase operation + * @reserve * */ struct cam_csiphy_acquire_dev_info { __u32 combo_mode; - __u32 reserved; + __u16 cphy_dphy_combo_mode; + __u8 csiphy_3phase; + __u8 reserve; } __attribute__((packed)); /**