static int msm_csid_config(struct csid_device *csid_dev, struct msm_camera_csid_params *csid_params) { int rc = 0; uint32_t val = 0, clk_rate = 0, round_rate = 0; struct clk **csid_clk_ptr; void __iomem *csidbase; csidbase = csid_dev->base; if (!csidbase || !csid_params) { pr_err("%s:%d csidbase %p, csid params %p\n", __func__, __LINE__, csidbase, csid_params); return -EINVAL; } CDBG("%s csid_params, lane_cnt = %d, lane_assign = 0x%x\n", __func__, csid_params->lane_cnt, csid_params->lane_assign); CDBG("%s csid_params phy_sel = %d\n", __func__, csid_params->phy_sel); msm_csid_reset(csid_dev); csid_clk_ptr = csid_dev->csid_clk; if (!csid_clk_ptr) { pr_err("csi_src_clk get failed\n"); return -EINVAL; } clk_rate = (csid_params->csi_clk > 0) ? (csid_params->csi_clk) : csid_dev->csid_max_clk; round_rate = clk_round_rate(csid_clk_ptr[csid_dev->csid_clk_index], clk_rate); if (round_rate > csid_dev->csid_max_clk) round_rate = csid_dev->csid_max_clk; pr_debug("usr set rate csi_clk clk_rate = %u round_rate = %u\n", clk_rate, round_rate); rc = clk_set_rate(csid_clk_ptr[csid_dev->csid_clk_index], round_rate); if (rc < 0) { pr_err("csi_src_clk set failed\n"); return rc; } val = csid_params->lane_cnt - 1; val |= csid_params->lane_assign << csid_dev->ctrl_reg->csid_reg.csid_dl_input_sel_shift; if (csid_dev->hw_version < 0x30000000) { val |= (0xF << 10); msm_camera_io_w(val, csidbase + csid_dev->ctrl_reg->csid_reg.csid_core_ctrl_0_addr); } else { msm_camera_io_w(val, csidbase + csid_dev->ctrl_reg->csid_reg.csid_core_ctrl_0_addr); val = csid_params->phy_sel << csid_dev->ctrl_reg->csid_reg.csid_phy_sel_shift; val |= 0xF; msm_camera_io_w(val, csidbase + csid_dev->ctrl_reg->csid_reg.csid_core_ctrl_1_addr); } rc = msm_csid_cid_lut(&csid_params->lut_params, csid_dev); if (rc < 0) return rc; msm_csid_set_debug_reg(csid_dev, csid_params); return rc; }
static int msm_csid_release(struct csid_device *csid_dev) { uint32_t irq; if (csid_dev->csid_state != CSID_POWER_UP) { pr_err("%s: csid invalid state %d\n", __func__, csid_dev->csid_state); return -EINVAL; } CDBG("%s:%d, hw_version = 0x%x\n", __func__, __LINE__, csid_dev->hw_version); irq = msm_camera_io_r(csid_dev->base + csid_dev->ctrl_reg->csid_reg.csid_irq_status_addr); msm_camera_io_w(irq, csid_dev->base + csid_dev->ctrl_reg->csid_reg.csid_irq_clear_cmd_addr); msm_camera_io_w(0, csid_dev->base + csid_dev->ctrl_reg->csid_reg.csid_irq_mask_addr); disable_irq(csid_dev->irq->start); if (csid_dev->hw_version == CSID_VERSION_V20) { msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info, csid_dev->csid_clk, csid_dev->num_clk, 0); msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } else if (csid_dev->hw_version == CSID_VERSION_V22) { msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info, csid_dev->csid_clk, csid_dev->num_clk, 0); msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } else if ((csid_dev->hw_version >= CSID_VERSION_V30 && csid_dev->hw_version < CSID_VERSION_V31) || (csid_dev->hw_version == CSID_VERSION_V40) || (csid_dev->hw_version == CSID_VERSION_V31_1) || (csid_dev->hw_version == CSID_VERSION_V31_3)) { msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info, csid_dev->csid_clk, csid_dev->num_clk, 0); msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } else if ((csid_dev->hw_version == CSID_VERSION_V31) || (csid_dev->hw_version == CSID_VERSION_V32) || (csid_dev->hw_version == CSID_VERSION_V33) || (csid_dev->hw_version == CSID_VERSION_V37) || (csid_dev->hw_version == CSID_VERSION_V34)) { msm_cam_clk_enable(&csid_dev->pdev->dev, csid_clk_info, csid_dev->csid_clk, csid_dev->num_clk, 0); msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } else { pr_err("%s:%d, invalid hw version : 0x%x", __func__, __LINE__, csid_dev->hw_version); return -EINVAL; } if (!IS_ERR_OR_NULL(csid_dev->reg_ptr)) { regulator_disable(csid_dev->reg_ptr); regulator_put(csid_dev->reg_ptr); } iounmap(csid_dev->base); csid_dev->base = NULL; csid_dev->csid_state = CSID_POWER_DOWN; return 0; }
static void msm_cci_flush_queue(struct cci_device *cci_dev, enum cci_i2c_master_t master) { int32_t rc = 0; #if defined(CONFIG_SONY_CAM_QCAMERA) uint8_t retry_count = 0; #endif msm_camera_io_w(1 << master, cci_dev->base + CCI_HALT_REQ_ADDR); #if defined(CONFIG_SONY_CAM_QCAMERA) retry_count = 4; do { rc = wait_for_completion_interruptible_timeout( &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); retry_count--; if (rc != -ERESTARTSYS) break; pr_debug("%s: wait_event interrupted by signal, count = %d", __func__, retry_count); msleep(20); } while (retry_count > 0); #else rc = wait_for_completion_interruptible_timeout( &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); #endif if (rc < 0) { pr_err("%s:%d wait failed\n", __func__, __LINE__); } else if (rc == 0) { pr_err("%s:%d wait timeout\n", __func__, __LINE__); /* Set reset pending flag to TRUE */ cci_dev->cci_master_info[master].reset_pending = TRUE; /* Set proper mask to RESET CMD address based on MASTER */ if (master == MASTER_0) msm_camera_io_w(CCI_M0_RESET_RMSK, cci_dev->base + CCI_RESET_CMD_ADDR); else msm_camera_io_w(CCI_M1_RESET_RMSK, cci_dev->base + CCI_RESET_CMD_ADDR); /* wait for reset done irq */ #if defined(CONFIG_SONY_CAM_QCAMERA) retry_count = 4; do { rc = wait_for_completion_interruptible_timeout( &cci_dev->cci_master_info[master].reset_complete , CCI_TIMEOUT); retry_count--; if (rc != -ERESTARTSYS) break; pr_debug("%s: wait_event interrupted by signal, count = %d", __func__, retry_count); msleep(20); } while (retry_count > 0); #else rc = wait_for_completion_interruptible_timeout( &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT); #endif if (rc <= 0) pr_err("%s:%d wait failed %d\n", __func__, __LINE__, rc); } return; }
static int msm_ispif_reset_hw(struct ispif_device *ispif, int release) { int rc = 0, i; long timeout = 0; struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)]; ispif->clk_idx = 0; rc = msm_ispif_get_clk_info(ispif, ispif->pdev, ispif_ahb_clk_info, ispif_clk_info); if (rc < 0) { pr_err("%s: msm_isp_get_clk_info() failed", __func__); return -EFAULT; } /* Turn ON regulators before enabling the clocks*/ rc = msm_ispif_set_regulator(ispif, 1); if (rc < 0) { pr_err("%s: ispif enable regulator failed", __func__); return -EFAULT; } rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info, ispif->clk, ispif->num_clk, 1); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d\n", __func__, rc); rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8626_reset_clk_info, reset_clk1, ARRAY_SIZE(ispif_8626_reset_clk_info), 1); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d", __func__, rc); } else { /* This is set when device is 8x26 */ ispif->clk_idx = 2; } } else { /* This is set when device is 8974 */ ispif->clk_idx = 1; } if (release) { for (i = 0; i < ispif->vfe_info.num_vfe; i++) { msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY, ispif->base + ISPIF_VFE_m_INTF_CMD_0(i)); msm_camera_io_w_mb(ISPIF_STOP_INTF_IMMEDIATELY, ispif->base + ISPIF_VFE_m_INTF_CMD_1(i)); } msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); } init_completion(&ispif->reset_complete[VFE0]); if (ispif->hw_num_isps > 1) init_completion(&ispif->reset_complete[VFE1]); /* initiate reset of ISPIF */ msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR); timeout = wait_for_completion_timeout( &ispif->reset_complete[VFE0], msecs_to_jiffies(500)); CDBG("%s: VFE0 done\n", __func__); if (timeout <= 0) { pr_err("%s: VFE0 reset wait timeout\n", __func__); rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info, ispif->clk, ispif->num_clk, 0); if (rc < 0) { rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8626_reset_clk_info, reset_clk1, ARRAY_SIZE(ispif_8626_reset_clk_info), 0); if (rc < 0) pr_err("%s: VFE0 reset wait timeout\n", __func__); } /* Turn OFF regulators */ rc = msm_ispif_set_regulator(ispif, 0); return -ETIMEDOUT; } if (ispif->hw_num_isps > 1) { msm_camera_io_w(ISPIF_RST_CMD_1_MASK, ispif->base + ISPIF_RST_CMD_1_ADDR); timeout = wait_for_completion_timeout( &ispif->reset_complete[VFE1], msecs_to_jiffies(500)); CDBG("%s: VFE1 done\n", __func__); if (timeout <= 0) { pr_err("%s: VFE1 reset wait timeout\n", __func__); rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info, ispif->clk, ispif->num_clk, 0); /* Turn OFF regulators */ rc = msm_ispif_set_regulator(ispif, 0); return -ETIMEDOUT; } } if (ispif->clk_idx == 1) { rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info, ispif->clk, ispif->num_clk, 0); if (rc < 0) { pr_err("%s: cannot disable clock, error = %d", __func__, rc); } } if (ispif->clk_idx == 2) { rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8626_reset_clk_info, reset_clk1, ARRAY_SIZE(ispif_8626_reset_clk_info), 0); if (rc < 0) { pr_err("%s: cannot disable clock, error = %d", __func__, rc); } } /* Turn OFF regulators after enabling the clocks*/ rc = msm_ispif_set_regulator(ispif, 0); if (rc < 0) { pr_err("%s: ispif disable regulator failed", __func__); return -EFAULT; } return rc; }
static int msm_ispif_config(struct ispif_device *ispif, struct msm_ispif_param_data *params) { int rc = 0, i = 0; uint16_t cid_mask; enum msm_ispif_intftype intftype; enum msm_ispif_vfe_intf vfe_intf; BUG_ON(!ispif); BUG_ON(!params); if (ispif->ispif_state != ISPIF_POWER_UP) { pr_err("%s: ispif invalid state %d\n", __func__, ispif->ispif_state); rc = -EPERM; return rc; } if (params->num > MAX_PARAM_ENTRIES) { pr_err("%s: invalid param entries %d\n", __func__, params->num); rc = -EINVAL; return rc; } for (i = 0; i < params->num; i++) { vfe_intf = params->entries[i].vfe_intf; if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { pr_err("%s: invalid interface type\n", __func__); return -EINVAL; } msm_camera_io_w(0x0, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe_intf)); msm_camera_io_w(0x0, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe_intf)); msm_camera_io_w_mb(0x0, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(vfe_intf)); } for (i = 0; i < params->num; i++) { intftype = params->entries[i].intftype; vfe_intf = params->entries[i].vfe_intf; CDBG("%s intftype %x, vfe_intf %d, csid %d\n", __func__, intftype, vfe_intf, params->entries[i].csid); if ((intftype >= INTF_MAX) || (vfe_intf >= ispif->vfe_info.num_vfe) || (ispif->csid_version <= CSID_VERSION_V22 && (vfe_intf > VFE0))) { pr_err("%s: VFEID %d and CSID version %d mismatch\n", __func__, vfe_intf, ispif->csid_version); return -EINVAL; } if (ispif->csid_version >= CSID_VERSION_V30) msm_ispif_select_clk_mux(ispif, intftype, params->entries[i].csid, vfe_intf); rc = msm_ispif_validate_intf_status(ispif, intftype, vfe_intf); if (rc) { pr_err("%s:validate_intf_status failed, rc = %d\n", __func__, rc); return rc; } msm_ispif_sel_csid_core(ispif, intftype, params->entries[i].csid, vfe_intf); cid_mask = msm_ispif_get_cids_mask_from_cfg( ¶ms->entries[i]); msm_ispif_enable_intf_cids(ispif, intftype, cid_mask, vfe_intf, 1); if (params->entries[i].crop_enable) msm_ispif_enable_crop(ispif, intftype, vfe_intf, params->entries[i].crop_start_pixel, params->entries[i].crop_end_pixel); } for (vfe_intf = 0; vfe_intf < 2; vfe_intf++) { msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(vfe_intf)); msm_camera_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(vfe_intf)); msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(vfe_intf)); msm_camera_io_w(ISPIF_IRQ_STATUS_1_MASK, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(vfe_intf)); msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(vfe_intf)); msm_camera_io_w(ISPIF_IRQ_STATUS_2_MASK, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(vfe_intf)); } msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); return rc; }
/* Later we can separate the rotation and scaler calc. If * rotation is enabled, simply swap the destination dimension. * And then pass the already swapped output size to this * function. */ static int vpe_update_scaler(struct msm_pp_crop *pcrop) { uint32_t out_ROI_width, out_ROI_height; uint32_t src_ROI_width, src_ROI_height; /* * phase_step_x, phase_step_y, phase_init_x and phase_init_y * are represented in fixed-point, unsigned 3.29 format */ uint32_t phase_step_x = 0; uint32_t phase_step_y = 0; uint32_t phase_init_x = 0; uint32_t phase_init_y = 0; uint32_t src_roi, src_x, src_y, src_xy, temp; uint32_t yscale_filter_sel, xscale_filter_sel; uint32_t scale_unit_sel_x, scale_unit_sel_y; uint64_t numerator, denominator; /* assumption is both direction need zoom. this can be improved. */ temp = msm_camera_io_r(vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET) | 0x3; msm_camera_io_w(temp, vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET); src_ROI_width = pcrop->src_w; src_ROI_height = pcrop->src_h; out_ROI_width = pcrop->dst_w; out_ROI_height = pcrop->dst_h; D("src w = 0x%x, h=0x%x, dst w = 0x%x, h =0x%x.\n", src_ROI_width, src_ROI_height, out_ROI_width, out_ROI_height); src_roi = (src_ROI_height << 16) + src_ROI_width; msm_camera_io_w(src_roi, vpe_ctrl->vpebase + VPE_SRC_SIZE_OFFSET); src_x = pcrop->src_x; src_y = pcrop->src_y; D("src_x = %d, src_y=%d.\n", src_x, src_y); src_xy = src_y*(1<<16) + src_x; msm_camera_io_w(src_xy, vpe_ctrl->vpebase + VPE_SRC_XY_OFFSET); D("src_xy = %d, src_roi=%d.\n", src_xy, src_roi); /* decide whether to use FIR or M/N for scaling */ if ((out_ROI_width == 1 && src_ROI_width < 4) || (src_ROI_width < 4 * out_ROI_width - 3)) scale_unit_sel_x = 0;/* use FIR scalar */ else scale_unit_sel_x = 1;/* use M/N scalar */ if ((out_ROI_height == 1 && src_ROI_height < 4) || (src_ROI_height < 4 * out_ROI_height - 3)) scale_unit_sel_y = 0;/* use FIR scalar */ else scale_unit_sel_y = 1;/* use M/N scalar */ /* calculate phase step for the x direction */ /* if destination is only 1 pixel wide, the value of phase_step_x is unimportant. Assigning phase_step_x to src ROI width as an arbitrary value. */ if (out_ROI_width == 1) phase_step_x = (uint32_t) ((src_ROI_width) << SCALER_PHASE_BITS); /* if using FIR scalar */ else if (scale_unit_sel_x == 0) { /* Calculate the quotient ( src_ROI_width - 1 ) ( out_ROI_width - 1) with u3.29 precision. Quotient is rounded up to the larger 29th decimal point*/ numerator = (uint64_t)(src_ROI_width - 1) << SCALER_PHASE_BITS; /* never equals to 0 because of the "(out_ROI_width == 1 )"*/ denominator = (uint64_t)(out_ROI_width - 1); /* divide and round up to the larger 29th decimal point.*/ phase_step_x = (uint32_t) vpe_do_div((numerator + denominator - 1), denominator); } else if (scale_unit_sel_x == 1) { /* if M/N scalar */ /* Calculate the quotient ( src_ROI_width ) / ( out_ROI_width) with u3.29 precision. Quotient is rounded down to the smaller 29th decimal point.*/ numerator = (uint64_t)(src_ROI_width) << SCALER_PHASE_BITS; denominator = (uint64_t)(out_ROI_width); phase_step_x = (uint32_t) vpe_do_div(numerator, denominator); } /* calculate phase step for the y direction */ /* if destination is only 1 pixel wide, the value of phase_step_x is unimportant. Assigning phase_step_x to src ROI width as an arbitrary value. */ if (out_ROI_height == 1) phase_step_y = (uint32_t) ((src_ROI_height) << SCALER_PHASE_BITS); /* if FIR scalar */ else if (scale_unit_sel_y == 0) { /* Calculate the quotient ( src_ROI_height - 1 ) / ( out_ROI_height - 1) with u3.29 precision. Quotient is rounded up to the larger 29th decimal point. */ numerator = (uint64_t)(src_ROI_height - 1) << SCALER_PHASE_BITS; /* never equals to 0 because of the " ( out_ROI_height == 1 )" case */ denominator = (uint64_t)(out_ROI_height - 1); /* Quotient is rounded up to the larger 29th decimal point. */ phase_step_y = (uint32_t) vpe_do_div( (numerator + denominator - 1), denominator); } else if (scale_unit_sel_y == 1) { /* if M/N scalar */ /* Calculate the quotient ( src_ROI_height ) ( out_ROI_height) with u3.29 precision. Quotient is rounded down to the smaller 29th decimal point. */ numerator = (uint64_t)(src_ROI_height) << SCALER_PHASE_BITS; denominator = (uint64_t)(out_ROI_height); phase_step_y = (uint32_t) vpe_do_div( numerator, denominator); } /* decide which set of FIR coefficients to use */ if (phase_step_x > HAL_MDP_PHASE_STEP_2P50) xscale_filter_sel = 0; else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66) xscale_filter_sel = 1; else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25) xscale_filter_sel = 2; else xscale_filter_sel = 3; if (phase_step_y > HAL_MDP_PHASE_STEP_2P50) yscale_filter_sel = 0; else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66) yscale_filter_sel = 1; else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25) yscale_filter_sel = 2; else yscale_filter_sel = 3; /* calculate phase init for the x direction */ /* if using FIR scalar */ if (scale_unit_sel_x == 0) { if (out_ROI_width == 1) phase_init_x = (uint32_t) ((src_ROI_width - 1) << SCALER_PHASE_BITS); else phase_init_x = 0; } else if (scale_unit_sel_x == 1) /* M over N scalar */ phase_init_x = 0; /* calculate phase init for the y direction if using FIR scalar */ if (scale_unit_sel_y == 0) { if (out_ROI_height == 1) phase_init_y = (uint32_t) ((src_ROI_height - 1) << SCALER_PHASE_BITS); else phase_init_y = 0; } else if (scale_unit_sel_y == 1) /* M over N scalar */ phase_init_y = 0; D("phase step x = %d, step y = %d.\n", phase_step_x, phase_step_y); D("phase init x = %d, init y = %d.\n", phase_init_x, phase_init_y); msm_camera_io_w(phase_step_x, vpe_ctrl->vpebase + VPE_SCALE_PHASEX_STEP_OFFSET); msm_camera_io_w(phase_step_y, vpe_ctrl->vpebase + VPE_SCALE_PHASEY_STEP_OFFSET); msm_camera_io_w(phase_init_x, vpe_ctrl->vpebase + VPE_SCALE_PHASEX_INIT_OFFSET); msm_camera_io_w(phase_init_y, vpe_ctrl->vpebase + VPE_SCALE_PHASEY_INIT_OFFSET); return 1; }
static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev, struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd, uint32_t *cfg_data, uint32_t cmd_len) { if (!vfe_dev || !reg_cfg_cmd) { pr_err("%s:%d failed: vfe_dev %p reg_cfg_cmd %p\n", __func__, __LINE__, vfe_dev, reg_cfg_cmd); return -EINVAL; } if ((reg_cfg_cmd->cmd_type != VFE_CFG_MASK) && (!cfg_data || !cmd_len)) { pr_err("%s:%d failed: cmd type %d cfg_data %p cmd_len %d\n", __func__, __LINE__, reg_cfg_cmd->cmd_type, cfg_data, cmd_len); return -EINVAL; } /* Validate input parameters */ switch (reg_cfg_cmd->cmd_type) { case VFE_WRITE: case VFE_READ: case VFE_WRITE_MB: { if ((reg_cfg_cmd->u.rw_info.reg_offset > (UINT_MAX - reg_cfg_cmd->u.rw_info.len)) || ((reg_cfg_cmd->u.rw_info.reg_offset + reg_cfg_cmd->u.rw_info.len) > resource_size(vfe_dev->vfe_mem))) { pr_err("%s:%d reg_offset %d len %d res %d\n", __func__, __LINE__, reg_cfg_cmd->u.rw_info.reg_offset, reg_cfg_cmd->u.rw_info.len, (uint32_t)resource_size(vfe_dev->vfe_mem)); return -EINVAL; } if ((reg_cfg_cmd->u.rw_info.cmd_data_offset > (UINT_MAX - reg_cfg_cmd->u.rw_info.len)) || ((reg_cfg_cmd->u.rw_info.cmd_data_offset + reg_cfg_cmd->u.rw_info.len) > cmd_len)) { pr_err("%s:%d cmd_data_offset %d len %d cmd_len %d\n", __func__, __LINE__, reg_cfg_cmd->u.rw_info.cmd_data_offset, reg_cfg_cmd->u.rw_info.len, cmd_len); return -EINVAL; } break; } case VFE_WRITE_DMI_16BIT: case VFE_WRITE_DMI_32BIT: case VFE_WRITE_DMI_64BIT: case VFE_READ_DMI_16BIT: case VFE_READ_DMI_32BIT: case VFE_READ_DMI_64BIT: { if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT || reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) { if ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset <= reg_cfg_cmd->u.dmi_info.lo_tbl_offset) || (reg_cfg_cmd->u.dmi_info.hi_tbl_offset - reg_cfg_cmd->u.dmi_info.lo_tbl_offset != (sizeof(uint32_t)))) { pr_err("%s:%d hi %d lo %d\n", __func__, __LINE__, reg_cfg_cmd->u.dmi_info.hi_tbl_offset, reg_cfg_cmd->u.dmi_info.hi_tbl_offset); return -EINVAL; } if (reg_cfg_cmd->u.dmi_info.len <= sizeof(uint32_t)) { pr_err("%s:%d len %d\n", __func__, __LINE__, reg_cfg_cmd->u.dmi_info.len); return -EINVAL; } if (((UINT_MAX - reg_cfg_cmd->u.dmi_info.hi_tbl_offset) < (reg_cfg_cmd->u.dmi_info.len - sizeof(uint32_t))) || ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset + reg_cfg_cmd->u.dmi_info.len - sizeof(uint32_t)) > cmd_len)) { pr_err("%s:%d hi_tbl_offset %d len %d cmd %d\n", __func__, __LINE__, reg_cfg_cmd->u.dmi_info.hi_tbl_offset, reg_cfg_cmd->u.dmi_info.len, cmd_len); return -EINVAL; } } if ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset > (UINT_MAX - reg_cfg_cmd->u.dmi_info.len)) || ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset + reg_cfg_cmd->u.dmi_info.len) > cmd_len)) { pr_err("%s:%d lo_tbl_offset %d len %d cmd_len %d\n", __func__, __LINE__, reg_cfg_cmd->u.dmi_info.lo_tbl_offset, reg_cfg_cmd->u.dmi_info.len, cmd_len); return -EINVAL; } break; } default: break; } switch (reg_cfg_cmd->cmd_type) { case VFE_WRITE: { msm_camera_io_memcpy(vfe_dev->vfe_base + reg_cfg_cmd->u.rw_info.reg_offset, cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4, reg_cfg_cmd->u.rw_info.len); break; } case VFE_WRITE_MB: { msm_camera_io_memcpy_mb(vfe_dev->vfe_base + reg_cfg_cmd->u.rw_info.reg_offset, cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4, reg_cfg_cmd->u.rw_info.len); break; } case VFE_CFG_MASK: { uint32_t temp; if ((UINT_MAX - sizeof(temp) < reg_cfg_cmd->u.mask_info.reg_offset) || (resource_size(vfe_dev->vfe_mem) < reg_cfg_cmd->u.mask_info.reg_offset + sizeof(temp))) { pr_err("%s: VFE_CFG_MASK: Invalid length\n", __func__); return -EINVAL; } temp = msm_camera_io_r(vfe_dev->vfe_base + reg_cfg_cmd->u.mask_info.reg_offset); temp &= ~reg_cfg_cmd->u.mask_info.mask; temp |= reg_cfg_cmd->u.mask_info.val; msm_camera_io_w(temp, vfe_dev->vfe_base + reg_cfg_cmd->u.mask_info.reg_offset); break; } case VFE_WRITE_DMI_16BIT: case VFE_WRITE_DMI_32BIT: case VFE_WRITE_DMI_64BIT: { int i; uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL; uint32_t hi_val, lo_val, lo_val1; if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) { hi_tbl_ptr = cfg_data + reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4; } lo_tbl_ptr = cfg_data + reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4; if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) { reg_cfg_cmd->u.dmi_info.len = reg_cfg_cmd->u.dmi_info.len/2; } for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) { lo_val = *lo_tbl_ptr++; if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_16BIT) { lo_val1 = lo_val & 0x0000FFFF; lo_val = (lo_val & 0xFFFF0000)>>16; msm_camera_io_w(lo_val1, vfe_dev->vfe_base + vfe_dev->hw_info->dmi_reg_offset + 0x4); } else if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) { lo_tbl_ptr++; hi_val = *hi_tbl_ptr; hi_tbl_ptr = hi_tbl_ptr + 2; msm_camera_io_w(hi_val, vfe_dev->vfe_base + vfe_dev->hw_info->dmi_reg_offset); } msm_camera_io_w(lo_val, vfe_dev->vfe_base + vfe_dev->hw_info->dmi_reg_offset + 0x4); } break; }
static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out, void *data) { struct ispif_device *ispif = (struct ispif_device *)data; BUG_ON(!ispif); BUG_ON(!out); out[VFE0].ispifIrqStatus0 = msm_camera_io_r(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(VFE0)); msm_camera_io_w(out[VFE0].ispifIrqStatus0, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(VFE0)); out[VFE0].ispifIrqStatus1 = msm_camera_io_r(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(VFE0)); msm_camera_io_w(out[VFE0].ispifIrqStatus1, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(VFE0)); out[VFE0].ispifIrqStatus2 = msm_camera_io_r(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(VFE0)); msm_camera_io_w_mb(out[VFE0].ispifIrqStatus2, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(VFE0)); if (ispif->vfe_info.num_vfe > 1) { out[VFE1].ispifIrqStatus0 = msm_camera_io_r(ispif->base + ISPIF_VFE_m_IRQ_STATUS_0(VFE1)); msm_camera_io_w(out[VFE1].ispifIrqStatus0, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(VFE1)); out[VFE1].ispifIrqStatus1 = msm_camera_io_r(ispif->base + ISPIF_VFE_m_IRQ_STATUS_1(VFE1)); msm_camera_io_w(out[VFE1].ispifIrqStatus1, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(VFE1)); out[VFE1].ispifIrqStatus2 = msm_camera_io_r(ispif->base + ISPIF_VFE_m_IRQ_STATUS_2(VFE1)); msm_camera_io_w_mb(out[VFE1].ispifIrqStatus2, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(VFE1)); } msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); if (out[VFE0].ispifIrqStatus0 & ISPIF_IRQ_STATUS_MASK) { if (out[VFE0].ispifIrqStatus0 & RESET_DONE_IRQ) complete(&ispif->reset_complete[VFE0]); if (out[VFE0].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ) pr_err("%s: VFE0 pix0 overflow.\n", __func__); if (out[VFE0].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ) pr_err("%s: VFE0 rdi0 overflow.\n", __func__); if (out[VFE0].ispifIrqStatus1 & RAW_INTF_1_OVERFLOW_IRQ) pr_err("%s: VFE0 rdi1 overflow.\n", __func__); if (out[VFE0].ispifIrqStatus2 & RAW_INTF_2_OVERFLOW_IRQ) pr_err("%s: VFE0 rdi2 overflow.\n", __func__); ispif_process_irq(ispif, out, VFE0); } if (ispif->hw_num_isps > 1) { if (out[VFE1].ispifIrqStatus0 & RESET_DONE_IRQ) complete(&ispif->reset_complete[VFE1]); if (out[VFE1].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ) pr_err("%s: VFE1 pix0 overflow.\n", __func__); if (out[VFE1].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ) pr_err("%s: VFE1 rdi0 overflow.\n", __func__); if (out[VFE1].ispifIrqStatus1 & RAW_INTF_1_OVERFLOW_IRQ) pr_err("%s: VFE1 rdi1 overflow.\n", __func__); if (out[VFE1].ispifIrqStatus2 & RAW_INTF_2_OVERFLOW_IRQ) pr_err("%s: VFE1 rdi2 overflow.\n", __func__); ispif_process_irq(ispif, out, VFE1); } }
static int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev, struct msm_camera_csiphy_params *csiphy_params) { int rc = 0; int j = 0, curr_lane = 0; uint32_t val = 0, clk_rate = 0, round_rate = 0; uint8_t lane_cnt = 0; uint16_t lane_mask = 0; void __iomem *csiphybase; uint8_t csiphy_id = csiphy_dev->pdev->id; int32_t lane_val = 0, lane_right = 0, num_lanes = 0; struct clk **csid_phy_clk_ptr; int ratio = 1; csiphybase = csiphy_dev->base; if (!csiphybase) { pr_err("%s: csiphybase NULL\n", __func__); return -EINVAL; } csiphy_dev->lane_mask[csiphy_id] |= csiphy_params->lane_mask; lane_mask = csiphy_dev->lane_mask[csiphy_id]; lane_cnt = csiphy_params->lane_cnt; if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) { pr_err("%s: unsupported lane cnt %d\n", __func__, csiphy_params->lane_cnt); return rc; } csid_phy_clk_ptr = csiphy_dev->csiphy_clk; if (!csid_phy_clk_ptr) { pr_err("csiphy_timer_src_clk get failed\n"); return -EINVAL; } clk_rate = (csiphy_params->csiphy_clk > 0) ? csiphy_params->csiphy_clk : csiphy_dev->csiphy_max_clk; round_rate = clk_round_rate( csid_phy_clk_ptr[csiphy_dev->csiphy_clk_index], clk_rate); if (round_rate >= csiphy_dev->csiphy_max_clk) round_rate = csiphy_dev->csiphy_max_clk; else { ratio = csiphy_dev->csiphy_max_clk/round_rate; csiphy_params->settle_cnt = csiphy_params->settle_cnt/ratio; } CDBG("set from usr csiphy_clk clk_rate = %u round_rate = %u\n", clk_rate, round_rate); rc = clk_set_rate( csid_phy_clk_ptr[csiphy_dev->csiphy_clk_index], round_rate); if (rc < 0) { pr_err("csiphy_timer_src_clk set failed\n"); return rc; } CDBG("%s csiphy_params, mask = 0x%x cnt = %d\n", __func__, csiphy_params->lane_mask, csiphy_params->lane_cnt); CDBG("%s csiphy_params, settle cnt = 0x%x csid %d\n", __func__, csiphy_params->settle_cnt, csiphy_params->csid_core); if (csiphy_dev->hw_version >= CSIPHY_VERSION_V30) { val = msm_camera_io_r(csiphy_dev->clk_mux_base); if (csiphy_params->combo_mode && (csiphy_params->lane_mask & 0x18) == 0x18) { val &= ~0xf0; val |= csiphy_params->csid_core << 4; } else { val &= ~0xf; val |= csiphy_params->csid_core; } msm_camera_io_w(val, csiphy_dev->clk_mux_base); CDBG("%s clk mux addr %p val 0x%x\n", __func__, csiphy_dev->clk_mux_base, val); mb(); } msm_camera_io_w(0x1, csiphybase + csiphy_dev->ctrl_reg-> csiphy_reg.mipi_csiphy_glbl_t_init_cfg0_addr); msm_camera_io_w(0x1, csiphybase + csiphy_dev->ctrl_reg-> csiphy_reg.mipi_csiphy_t_wakeup_cfg0_addr); if (csiphy_dev->hw_version < CSIPHY_VERSION_V30) { val = 0x3; msm_camera_io_w((lane_mask << 2) | val, csiphybase + csiphy_dev->ctrl_reg-> csiphy_reg.mipi_csiphy_glbl_pwr_cfg_addr); msm_camera_io_w(0x10, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnck_cfg2_addr); msm_camera_io_w(csiphy_params->settle_cnt, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnck_cfg3_addr); msm_camera_io_w(0x24, csiphybase + csiphy_dev->ctrl_reg-> csiphy_reg.mipi_csiphy_interrupt_mask0_addr); msm_camera_io_w(0x24, csiphybase + csiphy_dev->ctrl_reg-> csiphy_reg.mipi_csiphy_interrupt_clear0_addr); } else { val = 0x1; msm_camera_io_w((lane_mask << 1) | val, csiphybase + csiphy_dev->ctrl_reg-> csiphy_reg.mipi_csiphy_glbl_pwr_cfg_addr); msm_camera_io_w(csiphy_params->combo_mode << csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_mode_config_shift, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_glbl_reset_addr); } lane_mask &= 0x1f; while (lane_mask & 0x1f) { if (!(lane_mask & 0x1)) { j++; lane_mask >>= 1; continue; } msm_camera_io_w(0x10, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnn_cfg2_addr + 0x40*j); msm_camera_io_w(csiphy_params->settle_cnt, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnn_cfg3_addr + 0x40*j); /* add by lifeng for making sure release time of termination behind trail region for hi545(QL860) begin*/ msm_camera_io_w(csiphy_params->settle_cnt, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnn_cfg4_addr + 0x40*j); /* add by lifeng for making sure release time of termination behind trail region for hi545(QL860) end*/ msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_interrupt_mask_val, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_interrupt_mask_addr + 0x4*j); msm_camera_io_w(csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_interrupt_mask_val, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_interrupt_clear_addr + 0x4*j); if (csiphy_dev->is_3_1_20nm_hw == 1) { if (j > CLK_LANE_OFFSET) { lane_right = 0x8; num_lanes = (lane_cnt - curr_lane) << NUM_LANES_OFFSET; if (lane_cnt < curr_lane) { pr_err("%s: Lane_cnt is less than curr_lane number\n", __func__); return -EINVAL; } lane_val = lane_right|num_lanes; } else if (j == 1) { lane_val = 0x4; } if (csiphy_params->combo_mode == 1) { /* * In the case of combo mode, the clock is always * 4th lane for the second sensor. * So check whether the sensor is of one lane * sensor and curr_lane for 0. */ if (curr_lane == 0 && ((csiphy_params->lane_mask & 0x18) == 0x18)) lane_val = 0x4; } msm_camera_io_w(lane_val, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnn_misc1_addr + 0x40*j); msm_camera_io_w(0x17, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnn_test_imp + 0x40*j); curr_lane++; } j++; lane_mask >>= 1; }
static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev, struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd, uint32_t *cfg_data, uint32_t cmd_len) { switch (reg_cfg_cmd->cmd_type) { case VFE_WRITE: { if (resource_size(vfe_dev->vfe_mem) < (reg_cfg_cmd->u.rw_info.reg_offset + reg_cfg_cmd->u.rw_info.len)) { pr_err("%s: Invalid length\n", __func__); return -EINVAL; } msm_camera_io_memcpy(vfe_dev->vfe_base + reg_cfg_cmd->u.rw_info.reg_offset, cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset / 4, reg_cfg_cmd->u.rw_info.len); break; } case VFE_WRITE_MB: { uint32_t *data_ptr = cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset / 4; msm_camera_io_w_mb(*data_ptr, vfe_dev->vfe_base + reg_cfg_cmd->u.rw_info.reg_offset); break; } case VFE_CFG_MASK: { uint32_t temp; temp = msm_camera_io_r(vfe_dev->vfe_base + reg_cfg_cmd->u.mask_info.reg_offset); temp &= ~reg_cfg_cmd->u.mask_info.mask; temp |= reg_cfg_cmd->u.mask_info.val; msm_camera_io_w(temp, vfe_dev->vfe_base + reg_cfg_cmd->u.mask_info.reg_offset); break; } case VFE_WRITE_DMI_16BIT: case VFE_WRITE_DMI_32BIT: case VFE_WRITE_DMI_64BIT: { int i; uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL; uint32_t hi_val, lo_val, lo_val1; if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) { if (reg_cfg_cmd->u.dmi_info.hi_tbl_offset + reg_cfg_cmd->u.dmi_info.len > cmd_len) { pr_err("Invalid Hi Table out of bounds\n"); return -EINVAL; } hi_tbl_ptr = cfg_data + reg_cfg_cmd->u.dmi_info.hi_tbl_offset / 4; } if (reg_cfg_cmd->u.dmi_info.lo_tbl_offset + reg_cfg_cmd->u.dmi_info.len > cmd_len) { pr_err("Invalid Lo Table out of bounds\n"); return -EINVAL; } lo_tbl_ptr = cfg_data + reg_cfg_cmd->u.dmi_info.lo_tbl_offset / 4; if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) reg_cfg_cmd->u.dmi_info.len = reg_cfg_cmd->u.dmi_info.len / 2; for (i = 0; i < reg_cfg_cmd->u.dmi_info.len / 4; i++) { lo_val = *lo_tbl_ptr++; if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_16BIT) { lo_val1 = lo_val & 0x0000FFFF; lo_val = (lo_val & 0xFFFF0000) >> 16; msm_camera_io_w(lo_val1, vfe_dev->vfe_base + vfe_dev->hw_info->dmi_reg_offset + 0x4); } else if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) { lo_tbl_ptr++; hi_val = *hi_tbl_ptr; hi_tbl_ptr = hi_tbl_ptr + 2; msm_camera_io_w(hi_val, vfe_dev->vfe_base + vfe_dev->hw_info->dmi_reg_offset); } msm_camera_io_w(lo_val, vfe_dev->vfe_base + vfe_dev->hw_info->dmi_reg_offset + 0x4); } break; }
int msm_camio_csi_config(struct msm_camera_csi_params *csi_params) { int rc = 0; uint32_t val = 0; int i; CDBG("msm_camio_csi_config\n"); /* SOT_ECC_EN enable error correction for SYNC (data-lane) */ msm_camera_io_w(0x4, csibase + MIPI_PHY_CONTROL); /* SW_RST to the CSI core */ msm_camera_io_w(MIPI_PROTOCOL_CONTROL_SW_RST_BMSK, csibase + MIPI_PROTOCOL_CONTROL); /* PROTOCOL CONTROL */ val = MIPI_PROTOCOL_CONTROL_LONG_PACKET_HEADER_CAPTURE_BMSK | MIPI_PROTOCOL_CONTROL_DECODE_ID_BMSK | MIPI_PROTOCOL_CONTROL_ECC_EN_BMSK; val |= (uint32_t)(csi_params->data_format) << MIPI_PROTOCOL_CONTROL_DATA_FORMAT_SHFT; val |= csi_params->dpcm_scheme << MIPI_PROTOCOL_CONTROL_DPCM_SCHEME_SHFT; CDBG("%s MIPI_PROTOCOL_CONTROL val=0x%x\n", __func__, val); msm_camera_io_w(val, csibase + MIPI_PROTOCOL_CONTROL); /* SW CAL EN */ val = (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_CAL_EN_SHFT) | (0x1 << MIPI_CALIBRATION_CONTROL_SWCAL_STRENGTH_OVERRIDE_EN_SHFT) | (0x1 << MIPI_CALIBRATION_CONTROL_CAL_SW_HW_MODE_SHFT) | (0x1 << MIPI_CALIBRATION_CONTROL_MANUAL_OVERRIDE_EN_SHFT); CDBG("%s MIPI_CALIBRATION_CONTROL val=0x%x\n", __func__, val); msm_camera_io_w(val, csibase + MIPI_CALIBRATION_CONTROL); /* settle_cnt is very sensitive to speed! increase this value to run at higher speeds */ val = (csi_params->settle_cnt << MIPI_PHY_D0_CONTROL2_SETTLE_COUNT_SHFT) | (0x0F << MIPI_PHY_D0_CONTROL2_HS_TERM_IMP_SHFT) | (0x1 << MIPI_PHY_D0_CONTROL2_LP_REC_EN_SHFT) | (0x1 << MIPI_PHY_D0_CONTROL2_ERR_SOT_HS_EN_SHFT); CDBG("%s MIPI_PHY_D0_CONTROL2 val=0x%x\n", __func__, val); for (i = 0; i < csi_params->lane_cnt; i++) msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL2 + i * 4); val = (0x0F << MIPI_PHY_CL_CONTROL_HS_TERM_IMP_SHFT) | (0x1 << MIPI_PHY_CL_CONTROL_LP_REC_EN_SHFT); CDBG("%s MIPI_PHY_CL_CONTROL val=0x%x\n", __func__, val); msm_camera_io_w(val, csibase + MIPI_PHY_CL_CONTROL); val = 0 << MIPI_PHY_D0_CONTROL_HS_REC_EQ_SHFT; msm_camera_io_w(val, csibase + MIPI_PHY_D0_CONTROL); val = (0x1 << MIPI_PHY_D1_CONTROL_MIPI_CLK_PHY_SHUTDOWNB_SHFT) | (0x1 << MIPI_PHY_D1_CONTROL_MIPI_DATA_PHY_SHUTDOWNB_SHFT); CDBG("%s MIPI_PHY_D1_CONTROL val=0x%x\n", __func__, val); msm_camera_io_w(val, csibase + MIPI_PHY_D1_CONTROL); msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D2_CONTROL); msm_camera_io_w(0x00000000, csibase + MIPI_PHY_D3_CONTROL); /* halcyon only supports 1 or 2 lane */ switch (csi_params->lane_cnt) { case 1: msm_camera_io_w(csi_params->lane_assign << 8 | 0x4, csibase + MIPI_CAMERA_CNTL); break; case 2: msm_camera_io_w(csi_params->lane_assign << 8 | 0x5, csibase + MIPI_CAMERA_CNTL); break; case 3: msm_camera_io_w(csi_params->lane_assign << 8 | 0x6, csibase + MIPI_CAMERA_CNTL); break; case 4: msm_camera_io_w(csi_params->lane_assign << 8 | 0x7, csibase + MIPI_CAMERA_CNTL); break; } /* mask out ID_ERROR[19], DATA_CMM_ERR[11] and CLK_CMM_ERR[10] - de-featured */ msm_camera_io_w(0xFFF7F3FF, csibase + MIPI_INTERRUPT_MASK); /*clear IRQ bits*/ msm_camera_io_w(0xFFF7F3FF, csibase + MIPI_INTERRUPT_STATUS); return rc; }
static int msm_csid_release(struct csid_device *csid_dev) { uint32_t irq; /* LGE_CHANGE_S [[email protected]][20130625] : To enter the deep sleep after finish camera open , for google talk */ wake_unlock(&csid_dev->csid_wake_lock); /* LGE_CHANGE_E [[email protected]][20130625] : To enter the deep sleep after finish camera open , for google talk */ if (csid_dev->csid_state != CSID_POWER_UP) { pr_err("%s: csid invalid state %d\n", __func__, csid_dev->csid_state); return -EINVAL; } irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR); msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR); msm_camera_io_w(0, csid_dev->base + CSID_IRQ_MASK_ADDR); disable_irq(csid_dev->irq->start); if (csid_dev->hw_version == CSID_VERSION_V20) { msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info, csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0); msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } else if (csid_dev->hw_version == CSID_VERSION_V22) { msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8610_clk_info, csid_dev->csid_clk, ARRAY_SIZE(csid_8610_clk_info), 0); msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } else if (csid_dev->hw_version >= CSID_VERSION_V30) { msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8974_clk_info, csid_dev->csid_clk, ARRAY_SIZE(csid_8974_clk_info), 0); msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } iounmap(csid_dev->base); csid_dev->base = NULL; csid_dev->csid_state = CSID_POWER_DOWN; return 0; }
static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif, struct msm_ispif_param_data *params) { int rc = 0, i; long timeout = 0; uint16_t cid_mask; enum msm_ispif_intftype intftype; enum msm_ispif_vfe_intf vfe_intf; uint32_t vfe_mask = 0; uint32_t intf_addr; if (ispif->ispif_state != ISPIF_POWER_UP) { pr_err("%s: ispif invalid state %d\n", __func__, ispif->ispif_state); rc = -EPERM; return rc; } if (params->num > MAX_PARAM_ENTRIES) { pr_err("%s: invalid param entries %d\n", __func__, params->num); rc = -EINVAL; return rc; } for (i = 0; i < params->num; i++) { vfe_intf = params->entries[i].vfe_intf; if (vfe_intf >= VFE_MAX) { pr_err("%s: %d invalid i %d vfe_intf %d\n", __func__, __LINE__, i, vfe_intf); return -EINVAL; } vfe_mask |= (1 << vfe_intf); } /* Turn ON regulators before enabling the clocks*/ rc = msm_ispif_set_regulator(ispif, 1); if (rc < 0) { pr_err("%s: ispif enable regulator failed", __func__); return -EFAULT; } rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info, ispif->clk, ispif->num_clk, 1); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d", __func__, rc); goto disable_regulator; } if (vfe_mask & (1 << VFE0)) { init_completion(&ispif->reset_complete[VFE0]); /* initiate reset of ISPIF */ msm_camera_io_w(0x00001FF9, ispif->base + ISPIF_RST_CMD_ADDR); } if (vfe_mask & (1 << VFE0)) { timeout = wait_for_completion_timeout( &ispif->reset_complete[VFE0], msecs_to_jiffies(500)); if (timeout <= 0) { pr_err("%s: VFE0 reset wait timeout\n", __func__); rc = -ETIMEDOUT; goto disable_clk; } } if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) { init_completion(&ispif->reset_complete[VFE1]); msm_camera_io_w(0x00001FF9, ispif->base + ISPIF_RST_CMD_1_ADDR); } if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) { timeout = wait_for_completion_timeout( &ispif->reset_complete[VFE1], msecs_to_jiffies(500)); if (timeout <= 0) { pr_err("%s: VFE1 reset wait timeout\n", __func__); rc = -ETIMEDOUT; goto disable_clk; } } pr_info("%s: ISPIF reset hw done, Restarting", __func__); rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info, ispif->clk, ispif->num_clk, 0); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d", __func__, rc); goto disable_regulator; } /* Turn OFF regulators after disabling clocks */ rc = msm_ispif_set_regulator(ispif, 0); if (rc < 0) { pr_err("%s: ispif disable regulator failed", __func__); rc = -EFAULT; goto end; } for (i = 0; i < params->num; i++) { intftype = params->entries[i].intftype; vfe_intf = params->entries[i].vfe_intf; switch (params->entries[0].intftype) { case PIX0: intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0); break; case RDI0: intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0); break; case PIX1: intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1); break; case RDI1: intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1); break; case RDI2: intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2); break; default: pr_err("%s: invalid intftype=%d\n", __func__, params->entries[i].intftype); rc = -EPERM; goto end; } msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params); } for (i = 0; i < params->num; i++) { intftype = params->entries[i].intftype; vfe_intf = params->entries[i].vfe_intf; cid_mask = msm_ispif_get_cids_mask_from_cfg( ¶ms->entries[i]); msm_ispif_enable_intf_cids(ispif, intftype, cid_mask, vfe_intf, 1); } return rc; disable_clk: msm_cam_clk_enable(&ispif->pdev->dev, ispif_clk_info, ispif->clk, ispif->num_clk, 0); disable_regulator: /* Turn OFF regulators */ msm_ispif_set_regulator(ispif, 0); end: return rc; }
void msm_csid_reset(struct csid_device *csid_dev) { msm_camera_io_w(CSID_RST_STB_ALL, csid_dev->base + CSID_RST_CMD_ADDR); wait_for_completion_interruptible(&csid_dev->reset_complete); return; }
static int msm_ispif_intf_reset(struct ispif_device *ispif, struct msm_ispif_param_data *params) { int i, rc = 0; enum msm_ispif_intftype intf_type; int vfe_intf = 0; uint32_t data = 0; for (i = 0; i < params->num; i++) { data = STROBED_RST_EN; vfe_intf = params->entries[i].vfe_intf; intf_type = params->entries[i].intftype; ispif->sof_count[params->entries[i].vfe_intf]. sof_cnt[intf_type] = 0; switch (intf_type) { case PIX0: data |= (PIX_0_VFE_RST_STB | PIX_0_CSID_RST_STB); break; case RDI0: data |= (RDI_0_VFE_RST_STB | RDI_0_CSID_RST_STB); break; case PIX1: data |= (PIX_1_VFE_RST_STB | PIX_1_CSID_RST_STB); break; case RDI1: data |= (RDI_1_VFE_RST_STB | RDI_1_CSID_RST_STB); break; case RDI2: data |= (RDI_2_VFE_RST_STB | RDI_2_CSID_RST_STB); break; default: rc = -EINVAL; break; } if (data > 0x1) { unsigned long jiffes = msecs_to_jiffies(500); long lrc = 0; unsigned long flags; spin_lock_irqsave( &ispif->auto_complete_lock, flags); ispif->wait_timeout[vfe_intf] = 0; init_completion(&ispif->reset_complete[vfe_intf]); spin_unlock_irqrestore( &ispif->auto_complete_lock, flags); if (vfe_intf == VFE0) msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_ADDR); else msm_camera_io_w(data, ispif->base + ISPIF_RST_CMD_1_ADDR); lrc = wait_for_completion_interruptible_timeout( &ispif->reset_complete[vfe_intf], jiffes); if (lrc < 0 || !lrc) { pr_err("%s: wait timeout ret = %ld, vfe_id = %d\n", __func__, lrc, vfe_intf); rc = -EIO; spin_lock_irqsave( &ispif->auto_complete_lock, flags); ispif->wait_timeout[vfe_intf] = 1; spin_unlock_irqrestore( &ispif->auto_complete_lock, flags); } } } return rc; }
int msm_csid_release(struct csid_device *csid_dev, uint32_t bypass) { uint32_t irq; uint8_t core_id = 0; if (csid_dev->csid_state != CSID_POWER_UP) { pr_err("%s: csid invalid state %d\n", __func__, csid_dev->csid_state); return -EINVAL; } pr_err("%s - %d", __func__, csid_dev->refcnt-1); /* skip if reserved */ if (csid_dev->refcnt) { if (!csid_dev->reserved_adp) { msm_csid_soft_reset(csid_dev); pr_err("%s - resetting csid", __func__); } if (--csid_dev->refcnt) return 0; } else { pr_err("%s refcnt already 0!", __func__); } if (csid_dev->reserved_adp) { pr_err("%s - csid reserved!", __func__); return 0; } irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR); msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR); msm_camera_io_w(0, csid_dev->base + CSID_IRQ_MASK_ADDR); disable_irq(csid_dev->irq->start); if (csid_dev->hw_version <= CSID_VERSION_V2) { msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info, csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 0); if (!bypass) { msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } } else if (csid_dev->hw_version == CSID_VERSION_V3) { core_id = csid_dev->pdev->id; if (core_id) msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8974_clk_info[core_id].clk_info, csid_dev->csid_clk, csid_8974_clk_info[core_id].num_clk_info, 0); msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8974_clk_info[0].clk_info, csid_dev->csid0_clk, csid_8974_clk_info[0].num_clk_info, 0); if (!bypass) { msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); msm_camera_config_vreg(&csid_dev->pdev->dev, csid_8974_vreg_info, ARRAY_SIZE(csid_8974_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } } iounmap(csid_dev->base); csid_dev->base = NULL; csid_dev->csid_state = CSID_POWER_DOWN; return 0; }
static int msm_ispif_reset(struct ispif_device *ispif) { int rc = 0; long lrc = 0; unsigned long jiffes = msecs_to_jiffies(500); unsigned long flags; spin_lock_irqsave(&ispif->auto_complete_lock, flags); ispif->wait_timeout[VFE0] = 0; init_completion(&ispif->reset_complete[VFE0]); if (ispif->csid_version >= CSID_VERSION_V3 && ispif->vfe_info.num_vfe > 1) { ispif->wait_timeout[VFE1] = 0; init_completion(&ispif->reset_complete[VFE1]); } spin_unlock_irqrestore(&ispif->auto_complete_lock, flags); BUG_ON(!ispif); memset(ispif->sof_count, 0, sizeof(ispif->sof_count)); msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, ispif->base + ISPIF_VFE_m_INTF_CMD_0(0)); msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR); lrc = wait_for_completion_interruptible_timeout( &ispif->reset_complete[VFE0], jiffes); if (lrc < 0 || !lrc) { pr_err("%s: wait timeout ret = %ld, vfeid = %d\n", __func__, lrc, VFE0); rc = -EIO; spin_lock_irqsave(&ispif->auto_complete_lock, flags); ispif->wait_timeout[VFE0] = 1; spin_unlock_irqrestore(&ispif->auto_complete_lock, flags); goto end; } if (ispif->csid_version >= CSID_VERSION_V3 && ispif->vfe_info.num_vfe > 1) { msm_camera_io_w_mb(ISPIF_RST_CMD_1_MASK, ispif->base + ISPIF_RST_CMD_1_ADDR); lrc = wait_for_completion_interruptible_timeout( &ispif->reset_complete[VFE1], jiffes); if (lrc < 0 || !lrc) { pr_err("%s: wait timeout ret = %ld, vfeid = %d\n", __func__, lrc, VFE1); rc = -EIO; spin_lock_irqsave(&ispif->auto_complete_lock, flags); ispif->wait_timeout[VFE1] = 1; spin_unlock_irqrestore(&ispif->auto_complete_lock, flags); } } end: return rc; }
static int msm_ispif_reset_hw(struct ispif_device *ispif) { int rc = 0; long timeout = 0; struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)]; struct clk *reset_clk1[ARRAY_SIZE(ispif_8626_reset_clk_info)]; ispif->clk_idx = 0; rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 1); if (rc < 0) { rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8626_reset_clk_info, reset_clk1, ARRAY_SIZE(ispif_8626_reset_clk_info), 1); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d", __func__, rc); } else { /* This is set when device is 8x26 */ ispif->clk_idx = 2; } } else { /* This is set when device is 8974 */ ispif->clk_idx = 1; } init_completion(&ispif->reset_complete[VFE0]); if (ispif->hw_num_isps > 1) init_completion(&ispif->reset_complete[VFE1]); /* initiate reset of ISPIF */ msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR); if (ispif->hw_num_isps > 1) msm_camera_io_w(ISPIF_RST_CMD_1_MASK, ispif->base + ISPIF_RST_CMD_1_ADDR); timeout = wait_for_completion_timeout( &ispif->reset_complete[VFE0], msecs_to_jiffies(500)); CDBG("%s: VFE0 done\n", __func__); if (timeout <= 0) { pr_err("%s: VFE0 reset wait timeout\n", __func__); rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 0); if (rc < 0) { rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8626_reset_clk_info, reset_clk1, ARRAY_SIZE(ispif_8626_reset_clk_info), 0); if (rc < 0) pr_err("%s: VFE0 reset wait timeout\n", __func__); } return -ETIMEDOUT; } if (ispif->hw_num_isps > 1) { timeout = wait_for_completion_timeout( &ispif->reset_complete[VFE1], msecs_to_jiffies(500)); CDBG("%s: VFE1 done\n", __func__); if (timeout <= 0) { pr_err("%s: VFE1 reset wait timeout\n", __func__); msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 0); return -ETIMEDOUT; } } if (ispif->clk_idx == 1) { rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 0); if (rc < 0) { pr_err("%s: cannot disable clock, error = %d", __func__, rc); } } if (ispif->clk_idx == 2) { rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8626_reset_clk_info, reset_clk1, ARRAY_SIZE(ispif_8626_reset_clk_info), 0); if (rc < 0) { pr_err("%s: cannot disable clock, error = %d", __func__, rc); } } return rc; }
static int msm_ispif_reset_hw(struct ispif_device *ispif) { int rc = 0; long timeout = 0; struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)]; if (ispif->csid_version < CSID_VERSION_V30) { /* currently reset is done only for 8974 */ return 0; } rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 1); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d", __func__, rc); } init_completion(&ispif->reset_complete[VFE0]); if (ispif->hw_num_isps > 1) init_completion(&ispif->reset_complete[VFE1]); /* initiate reset of ISPIF */ msm_camera_io_w(ISPIF_RST_CMD_MASK, ispif->base + ISPIF_RST_CMD_ADDR); if (ispif->hw_num_isps > 1) msm_camera_io_w(ISPIF_RST_CMD_1_MASK, ispif->base + ISPIF_RST_CMD_1_ADDR); timeout = wait_for_completion_interruptible_timeout( &ispif->reset_complete[VFE0], msecs_to_jiffies(500)); CDBG("%s: VFE0 done\n", __func__); if (timeout <= 0) { pr_err("%s: VFE0 reset wait timeout\n", __func__); rc = -ETIMEDOUT; goto end; } if (ispif->hw_num_isps > 1) { timeout = wait_for_completion_interruptible_timeout( &ispif->reset_complete[VFE1], msecs_to_jiffies(500)); CDBG("%s: VFE1 done\n", __func__); if (timeout <= 0) { pr_err("%s: VFE1 reset wait timeout\n", __func__); rc = -ETIMEDOUT; goto end; } } pr_info("%s: ISPIF reset hw done", __func__); end: rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 0); if (rc < 0) { pr_err("%s: cannot disable clock, error = %d", __func__, rc); } return rc; }
static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif, struct msm_ispif_param_data *params) { int rc = 0, i; long timeout = 0; uint16_t cid_mask; enum msm_ispif_intftype intftype; enum msm_ispif_vfe_intf vfe_intf; uint32_t vfe_mask = 0; uint32_t intf_addr; struct clk *reset_clk[ARRAY_SIZE(ispif_8974_reset_clk_info)]; if (ispif->ispif_state != ISPIF_POWER_UP) { pr_err("%s: ispif invalid state %d\n", __func__, ispif->ispif_state); rc = -EPERM; return rc; } for (i = 0; i < params->num; i++) { vfe_intf = params->entries[i].vfe_intf; vfe_mask |= (1 << vfe_intf); } rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 1); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d", __func__, rc); goto end; } if (vfe_mask & (1 << VFE0)) { init_completion(&ispif->reset_complete[VFE0]); pr_err("%s Init completion VFE0\n", __func__); /* initiate reset of ISPIF */ msm_camera_io_w(0x00001FF9, ispif->base + ISPIF_RST_CMD_ADDR); } if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) { init_completion(&ispif->reset_complete[VFE1]); pr_err("%s Init completion VFE1\n", __func__); msm_camera_io_w(0x00001FF9, ispif->base + ISPIF_RST_CMD_1_ADDR); } if (vfe_mask & (1 << VFE0)) { timeout = wait_for_completion_interruptible_timeout( &ispif->reset_complete[VFE0], msecs_to_jiffies(500)); if (timeout <= 0) { pr_err("%s: VFE0 reset wait timeout\n", __func__); rc = -ETIMEDOUT; goto disable_clk; } } if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) { timeout = wait_for_completion_interruptible_timeout( &ispif->reset_complete[VFE1], msecs_to_jiffies(500)); if (timeout <= 0) { pr_err("%s: VFE1 reset wait timeout\n", __func__); rc = -ETIMEDOUT; goto disable_clk; } } pr_info("%s: ISPIF reset hw done", __func__); rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 0); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d", __func__, rc); goto end; } for (i = 0; i < params->num; i++) { intftype = params->entries[i].intftype; vfe_intf = params->entries[i].vfe_intf; switch (params->entries[0].intftype) { case PIX0: intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0); break; case RDI0: intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0); break; case PIX1: intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1); break; case RDI1: intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1); break; case RDI2: intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2); break; default: pr_err("%s: invalid intftype=%d\n", __func__, params->entries[i].intftype); rc = -EPERM; goto end; } msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params); } for (i = 0; i < params->num; i++) { intftype = params->entries[i].intftype; vfe_intf = params->entries[i].vfe_intf; cid_mask = msm_ispif_get_cids_mask_from_cfg( ¶ms->entries[i]); msm_ispif_enable_intf_cids(ispif, intftype, cid_mask, vfe_intf, 1); } end: return rc; disable_clk: rc = msm_cam_clk_enable(&ispif->pdev->dev, ispif_8974_reset_clk_info, reset_clk, ARRAY_SIZE(ispif_8974_reset_clk_info), 0); if (rc < 0) { pr_err("%s: cannot enable clock, error = %d", __func__, rc); } return -ETIMEDOUT; }
int msm_csiphy_lane_config(struct csiphy_device *csiphy_dev, struct msm_camera_csiphy_params *csiphy_params) { int rc = 0; int j = 0; uint32_t val = 0; uint8_t lane_cnt = 0; uint16_t lane_mask = 0; void __iomem *csiphybase; int i = 0; for(i=0; i<8; i++) memset(&csiphyErrStatus[i][1], 0, sizeof(uint8_t)); csiphybase = csiphy_dev->base; if (!csiphybase) { pr_err("%s: csiphybase NULL\n", __func__); return -EINVAL; } csiphy_dev->lane_mask[csiphy_dev->pdev->id] |= csiphy_params->lane_mask; lane_mask = csiphy_dev->lane_mask[csiphy_dev->pdev->id]; lane_cnt = csiphy_params->lane_cnt; if (csiphy_params->lane_cnt < 1 || csiphy_params->lane_cnt > 4) { pr_err("%s: unsupported lane cnt %d\n", __func__, csiphy_params->lane_cnt); return rc; } CDBG("%s csiphy_params, mask = %x, cnt = %d, settle cnt = %x\n", __func__, csiphy_params->lane_mask, csiphy_params->lane_cnt, csiphy_params->settle_cnt); msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_GLBL_T_INIT_CFG0_ADDR); msm_camera_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR); if (csiphy_dev->hw_version != CSIPHY_VERSION_V3) { val = 0x3; msm_camera_io_w((lane_mask << 2) | val, csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR); msm_camera_io_w(0x10, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR); msm_camera_io_w(csiphy_params->settle_cnt, csiphybase + MIPI_CSIPHY_LNCK_CFG3_ADDR); msm_camera_io_w(0x24, csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR); msm_camera_io_w(0x24, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR0_ADDR); } else { val = 0x1; msm_camera_io_w((lane_mask << 1) | val, csiphybase + MIPI_CSIPHY_GLBL_PWR_CFG_ADDR); msm_camera_io_w(csiphy_params->combo_mode << MIPI_CSIPHY_MODE_CONFIG_SHIFT, csiphybase + MIPI_CSIPHY_GLBL_RESET_ADDR); } lane_mask &= 0x1f; while (lane_mask & 0x1f) { if (!(lane_mask & 0x1)) { j++; lane_mask >>= 1; continue; } msm_camera_io_w(0x10, csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*j); msm_camera_io_w(csiphy_params->settle_cnt, csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*j); msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase + MIPI_CSIPHY_INTERRUPT_MASK_ADDR + 0x4*j); msm_camera_io_w(MIPI_CSIPHY_INTERRUPT_MASK_VAL, csiphybase + MIPI_CSIPHY_INTERRUPT_CLEAR_ADDR + 0x4*j); j++; lane_mask >>= 1; }
static int32_t msm_cci_validate_queue(struct cci_device *cci_dev, uint32_t len, enum cci_i2c_master_t master, enum cci_i2c_queue_t queue) { int32_t rc = 0; uint32_t read_val = 0; uint32_t reg_offset = master * 0x200 + queue * 0x100; #if defined(CONFIG_SONY_CAM_QCAMERA) uint8_t retry_count = 0; #endif read_val = msm_camera_io_r(cci_dev->base + CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset); CDBG("%s line %d CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR %d len %d max %d\n", __func__, __LINE__, read_val, len, cci_dev->cci_i2c_queue_info[master][queue].max_queue_size); if ((read_val + len + 1) > cci_dev-> cci_i2c_queue_info[master][queue].max_queue_size) { uint32_t reg_val = 0; uint32_t report_val = CCI_I2C_REPORT_CMD | (1 << 8); CDBG("%s:%d CCI_I2C_REPORT_CMD\n", __func__, __LINE__); msm_camera_io_w(report_val, cci_dev->base + CCI_I2C_M0_Q0_LOAD_DATA_ADDR + reg_offset); read_val++; CDBG("%s:%d CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR %d\n", __func__, __LINE__, read_val); msm_camera_io_w(read_val, cci_dev->base + CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset); reg_val = 1 << ((master * 2) + queue); CDBG("%s:%d CCI_QUEUE_START_ADDR\n", __func__, __LINE__); msm_camera_io_w(reg_val, cci_dev->base + CCI_QUEUE_START_ADDR); CDBG("%s line %d wait_for_completion_interruptible\n", __func__, __LINE__); #if defined(CONFIG_SONY_CAM_QCAMERA) retry_count = 4; do { rc = wait_for_completion_interruptible_timeout( &cci_dev->cci_master_info[master].reset_complete , CCI_TIMEOUT); retry_count--; if (rc != -ERESTARTSYS) break; pr_debug("%s: wait_event interrupted by signal, count = %d", __func__, retry_count); msleep(20); } while (retry_count > 0); #else rc = wait_for_completion_interruptible_timeout(&cci_dev-> cci_master_info[master].reset_complete, CCI_TIMEOUT); #endif if (rc <= 0) { pr_err("%s: wait_for_completion_interruptible_timeout %d\n", __func__, __LINE__); if (rc == 0) rc = -ETIMEDOUT; msm_cci_flush_queue(cci_dev, master); return rc; } rc = cci_dev->cci_master_info[master].status; if (rc < 0) pr_err("%s failed rc %d\n", __func__, rc); } return rc; }
static int msm_ispif_reset(struct ispif_device *ispif) { int rc = 0; int i; BUG_ON(!ispif); memset(ispif->sof_count, 0, sizeof(ispif->sof_count)); for (i = 0; i < ispif->vfe_info.num_vfe; i++) { msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT, ispif->base + ISPIF_VFE_m_CTRL_0(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i)); msm_camera_io_w(0xFFFFFFFF, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(i)); msm_camera_io_w(0xFFFFFFFF, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(i)); msm_camera_io_w(0xFFFFFFFF, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INPUT_SEL(i)); msm_camera_io_w(0xAAAAAAAA, ispif->base + ISPIF_VFE_m_INTF_CMD_0(i)); msm_camera_io_w(0xAAAAAAAA, ispif->base + ISPIF_VFE_m_INTF_CMD_1(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 2)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CROP(i, 0)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CROP(i, 1)); } msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); return rc; }
static int msm_ispif_reset(struct ispif_device *ispif) { int rc = 0; int i; // memset(ispif->sof_count, 0, sizeof(ispif->sof_count)); for (i = 0; i < ispif->vfe_info.num_vfe; i++) { msm_camera_io_w(1 << PIX0_LINE_BUF_EN_BIT, ispif->base + ISPIF_VFE_m_CTRL_0(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_0(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_1(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_IRQ_MASK_2(i)); msm_camera_io_w(0xFFFFFFFF, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_0(i)); msm_camera_io_w(0xFFFFFFFF, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_1(i)); msm_camera_io_w(0xFFFFFFFF, ispif->base + ISPIF_VFE_m_IRQ_CLEAR_2(i)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_INPUT_SEL(i)); msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, ispif->base + ISPIF_VFE_m_INTF_CMD_0(i)); msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY, ispif->base + ISPIF_VFE_m_INTF_CMD_1(i)); pr_debug("%s: base %x", __func__, (unsigned int)ispif->base); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1)); /* */ #if 0 msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 0)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 1)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 2)); #else msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 0)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 1)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 2)); #endif /* */ msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CROP(i, 0)); msm_camera_io_w(0, ispif->base + ISPIF_VFE_m_PIX_INTF_n_CROP(i, 1)); } msm_camera_io_w_mb(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base + ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR); return rc; }
static void set_vbif_params(struct msm_jpeg_device *pgmn_dev, void *jpeg_vbif_base) { msm_camera_io_w(0x1, jpeg_vbif_base + JPEG_VBIF_CLKON); if (pgmn_dev->hw_version != JPEG_8994) { msm_camera_io_w(0x10101010, jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF0); msm_camera_io_w(0x10101010, jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF1); msm_camera_io_w(0x10101010, jpeg_vbif_base + JPEG_VBIF_IN_RD_LIM_CONF2); msm_camera_io_w(0x10101010, jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF0); msm_camera_io_w(0x10101010, jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF1); msm_camera_io_w(0x10101010, jpeg_vbif_base + JPEG_VBIF_IN_WR_LIM_CONF2); msm_camera_io_w(0x00001010, jpeg_vbif_base + JPEG_VBIF_OUT_RD_LIM_CONF0); msm_camera_io_w(0x00000110, jpeg_vbif_base + JPEG_VBIF_OUT_WR_LIM_CONF0); msm_camera_io_w(0x00000707, jpeg_vbif_base + JPEG_VBIF_DDR_OUT_MAX_BURST); msm_camera_io_w(0x00000FFF, jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO_EN); msm_camera_io_w(0x0FFF0FFF, jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AOOO); msm_camera_io_w(0x2222, jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF1); } msm_camera_io_w(0x7, jpeg_vbif_base + JPEG_VBIF_OCMEM_OUT_MAX_BURST); msm_camera_io_w(0x00000030, jpeg_vbif_base + JPEG_VBIF_ARB_CTL); /*FE and WE QOS configuration need to be set when QOS RR arbitration is enabled*/ if (pgmn_dev->hw_version != JPEG_8974_V1) msm_camera_io_w(0x00000003, jpeg_vbif_base + JPEG_VBIF_ROUND_ROBIN_QOS_ARB); else msm_camera_io_w(0x00000001, jpeg_vbif_base + JPEG_VBIF_ROUND_ROBIN_QOS_ARB); msm_camera_io_w(0x22222222, jpeg_vbif_base + JPEG_VBIF_OUT_AXI_AMEMTYPE_CONF0); }