static int msm_ispif_validate_intf_status(struct ispif_device *ispif, uint8_t intftype, uint8_t vfe_intf) { int rc = 0; uint32_t data = 0; BUG_ON(!ispif); if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { pr_err("%s: invalid interface type\n", __func__); return -EINVAL; } switch (intftype) { case PIX0: data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0)); break; case RDI0: data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0)); break; case PIX1: data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1)); break; case RDI1: data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1)); break; case RDI2: data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2)); break; } if ((data & 0xf) != 0xf) rc = -EBUSY; return rc; }
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; 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__); rc = wait_for_completion_interruptible_timeout(&cci_dev-> cci_master_info[master].reset_complete, CCI_TIMEOUT); if (rc == -ERESTARTSYS) { pr_err("%s:%d failed: rc %d", __func__, __LINE__, rc); } else 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; } else { rc = cci_dev->cci_master_info[master].status; if (rc < 0) pr_err("%s failed rc %d\n", __func__, rc); } } return rc; }
void msm_camio_camif_pad_reg_reset(void) { uint32_t reg; msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL); usleep_range(10000, 11000); reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK; reg |= 0x3; msm_camera_io_w(reg, camifpadbase); usleep_range(10000, 11000); reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK; reg |= 0x10; msm_camera_io_w(reg, camifpadbase); usleep_range(10000, 11000); reg = (msm_camera_io_r(camifpadbase)) & CAMIF_CFG_RMSK; /* Need to be uninverted*/ reg &= 0x03; msm_camera_io_w(reg, camifpadbase); usleep_range(10000, 11000); }
static irqreturn_t msm_csid_irq(int irq_num, void *data) { uint32_t irq; struct csid_device *csid_dev = data; if (!csid_dev||!csid_dev->base) { pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__); return IRQ_HANDLED; } irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR); CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n", __func__, csid_dev->pdev->id, irq); if (irq & (0x1 << CSID_RST_DONE_IRQ_BITSHIFT)) complete(&csid_dev->reset_complete); if (irq & CSID_IRQ_UNBOUNDED_FRAME_MASK) pr_err("%s - received CSID_IRQ_UNBOUNDED_FRAME_MASK!\n", __func__); if (irq & CSID_IRQ_STREAM_UNDERFLOW_MASK) { pr_err("%s - received CSID_IRQ_STREAM_UNDERFLOW_MASK!\n", __func__); v4l2_subdev_notify(&csid_dev->subdev, NOTIFY_CSID_STREAM_UNDERFLOW_ERROR, (void *)NULL); } if (irq & CSID_IRQ_ECC_MASK) { pr_err("%s - received CSID_IRQ_ECC_MASK!\n", __func__); v4l2_subdev_notify(&csid_dev->subdev, NOTIFY_CSID_ECC_ERROR, (void *)NULL); } if (irq & CSID_IRQ_CRC_MASK) { pr_err("%s - received CSID_IRQ_CRC_MASK!\n", __func__); v4l2_subdev_notify(&csid_dev->subdev, NOTIFY_CSID_CRC_ERROR, (void *)NULL); } if (irq & CSID_IRQ_PHY_DL_OVERFLOW_MASK) { pr_err("%s - received CSID_IRQ_PHY_DL_OVERFLOW_MASK!\n", __func__); v4l2_subdev_notify(&csid_dev->subdev, NOTIFY_CSID_PHY_DL_OVERFLOW_ERROR, (void *)NULL); } msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR); return IRQ_HANDLED; }
static irqreturn_t msm_csid_irq(int irq_num, void *data) { uint32_t irq; struct csid_device *csid_dev = data; if (!csid_dev||!csid_dev->base) { pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__); return IRQ_HANDLED; } irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR); pr_err("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n", __func__, csid_dev->pdev->id, irq); if (irq & (0x1 << CSID_RST_DONE_IRQ_BITSHIFT)) complete(&csid_dev->reset_complete); msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR); return IRQ_HANDLED; }
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; } 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); 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) { 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_vpe_cfg_update(void *pinfo) { uint32_t rot_flag, rc = 0; struct msm_pp_crop *pcrop = (struct msm_pp_crop *)pinfo; rot_flag = msm_camera_io_r(vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET) & 0xE00; if (pinfo != NULL) { D("%s: Crop info in2_w = %d, in2_h = %d " "out2_w = %d out2_h = %d\n", __func__, pcrop->src_w, pcrop->src_h, pcrop->dst_w, pcrop->dst_h); rc = vpe_update_scaler(pcrop); } D("return rc = %d rot_flag = %d\n", rc, rot_flag); rc |= rot_flag; return rc; }
static void msm_ispif_enable_intf_cids(struct ispif_device *ispif, uint8_t intftype, uint16_t cid_mask, uint8_t vfe_intf, uint8_t enable) { uint32_t intf_addr, data; BUG_ON(!ispif); if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { pr_err("%s: invalid interface type\n", __func__); return; } switch (intftype) { case PIX0: intf_addr = ISPIF_VFE_m_PIX_INTF_n_CID_MASK(vfe_intf, 0); break; case RDI0: intf_addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe_intf, 0); break; case PIX1: intf_addr = ISPIF_VFE_m_PIX_INTF_n_CID_MASK(vfe_intf, 1); break; case RDI1: intf_addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe_intf, 1); break; case RDI2: intf_addr = ISPIF_VFE_m_RDI_INTF_n_CID_MASK(vfe_intf, 2); break; default: pr_err("%s: invalid intftype=%d\n", __func__, intftype); BUG_ON(1); return; } data = msm_camera_io_r(ispif->base + intf_addr); if (enable) data |= cid_mask; else data &= ~cid_mask; pr_err("%s: <DBG01> vfe_intf %u intftype %u intf_addr %x data %x\n", __func__, vfe_intf, intftype, intf_addr, data); msm_camera_io_w_mb(data, ispif->base + intf_addr); }
int msm_vpe_cfg_update(void *pinfo) { uint32_t rot_flag, rc = 0; struct video_crop_t *pcrop = (struct video_crop_t *)pinfo; rot_flag = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET) & 0xE00; if (pinfo != NULL) { CDBG("Crop info in2_w = %d, in2_h = %d " "out2_h = %d out2_w = %d \n", pcrop->in2_w, pcrop->in2_h, pcrop->out2_h, pcrop->out2_w); rc = vpe_update_scaler(pcrop); } CDBG("return rc = %d rot_flag = %d\n", rc, rot_flag); rc |= rot_flag; return rc; }
/*=========================================================================== * FUNCTION - read_packet_work_handler - * * DESCRIPTION: hander function *==========================================================================*/ static void read_packet_work_handler(struct work_struct *work) { struct csid_device *csid_dev = container_of(work, struct csid_device,packet_num_work.work); uint32_t value = 0; if(!csid_dev || !csid_dev->base) { pr_err("%s:%d\n",__func__,__LINE__); return; } value = msm_camera_io_r(csid_dev->base + CSID_STATS_TOTAL_PKTS_RCVD_ADDR); pr_info("%s: csid total packet[%d] = %u\n",__func__,read_times,value); read_times--; if(read_times > 0) { schedule_delayed_work(&csid_dev->packet_num_work, msecs_to_jiffies(HW_READ_PACKET_NUM_TIME)); } }
static int vpe_operation_config(uint32_t *p) { uint32_t outw, outh, temp; msm_camera_io_w(*p, vpe_device->vpebase + VPE_OP_MODE_OFFSET); temp = msm_camera_io_r(vpe_device->vpebase + VPE_OUT_SIZE_OFFSET); outw = temp & 0xFFF; outh = (temp & 0xFFF0000) >> 16; if (*p++ & 0xE00) { /* rotation enabled. */ vpe_ctrl->out_w = outh; vpe_ctrl->out_h = outw; } else { vpe_ctrl->out_w = outw; vpe_ctrl->out_h = outh; } vpe_ctrl->dis_en = *p; return 0; }
static irqreturn_t msm_csid_irq(int irq_num, void *data) { uint32_t irq; struct csid_device *csid_dev = data; if (!csid_dev) { pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__); return IRQ_HANDLED; } irq = msm_camera_io_r(csid_dev->base + csid_dev->ctrl_reg->csid_reg.csid_irq_status_addr); CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n", __func__, csid_dev->pdev->id, irq); if (irq & (0x1 << csid_dev->ctrl_reg->csid_reg.csid_rst_done_irq_bitshift)) complete(&csid_dev->reset_complete); msm_camera_io_w(irq, csid_dev->base + csid_dev->ctrl_reg->csid_reg.csid_irq_clear_cmd_addr); return IRQ_HANDLED; }
static int vpe_operation_config(uint32_t *p) { uint32_t w, h, temp; msm_camera_io_w(*p, vpe_ctrl->vpebase + VPE_OP_MODE_OFFSET); temp = msm_camera_io_r(vpe_ctrl->vpebase + VPE_OUT_SIZE_OFFSET); w = temp & 0xFFF; h = (temp & 0xFFF0000) >> 16; if (*p++ & 0xE00) { /* rotation enabled. */ vpe_ctrl->out_w = h; vpe_ctrl->out_h = w; } else { vpe_ctrl->out_w = w; vpe_ctrl->out_h = h; } D("%s: out_w=%d, out_h=%d", __func__, vpe_ctrl->out_w, vpe_ctrl->out_h); return 0; }
static void msm_ispif_sel_csid_core(struct ispif_device *ispif, uint8_t intftype, uint8_t csid, uint8_t vfe_intf) { uint32_t data; BUG_ON(!ispif); if (!msm_ispif_is_intf_valid(ispif->csid_version, vfe_intf)) { pr_err("%s: invalid interface type\n", __func__); return; } data = msm_camera_io_r(ispif->base + ISPIF_VFE_m_INPUT_SEL(vfe_intf)); switch (intftype) { case PIX0: data &= ~(BIT(1) | BIT(0)); data |= csid; break; case RDI0: data &= ~(BIT(5) | BIT(4)); data |= (csid << 4); break; case PIX1: data &= ~(BIT(9) | BIT(8)); data |= (csid << 8); break; case RDI1: data &= ~(BIT(13) | BIT(12)); data |= (csid << 12); break; case RDI2: data &= ~(BIT(21) | BIT(20)); data |= (csid << 20); break; } msm_camera_io_w_mb(data, ispif->base + ISPIF_VFE_m_INPUT_SEL(vfe_intf)); }
static int msm_csid_release(struct csid_device *csid_dev) { uint32_t irq; 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); 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) { 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_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; return 0; }
static int msm_i2c_mux_init(struct i2c_mux_device *mux_device) { int rc = 0, val = 0; if (mux_device->use_count == 0) { mux_device->ctl_base = ioremap(mux_device->ctl_mem->start, resource_size(mux_device->ctl_mem)); if (!mux_device->ctl_base) { rc = -ENOMEM; return rc; } mux_device->rw_base = ioremap(mux_device->rw_mem->start, resource_size(mux_device->rw_mem)); if (!mux_device->rw_base) { rc = -ENOMEM; iounmap(mux_device->ctl_base); return rc; } val = msm_camera_io_r(mux_device->rw_base); msm_camera_io_w((val | 0x200), mux_device->rw_base); } mux_device->use_count++; return 0; };
static void vpe_do_tasklet(unsigned long data) { unsigned long flags; uint32_t pyaddr = 0, pcbcraddr = 0; uint32_t src_y, src_cbcr, temp; struct vpe_isr_queue_cmd_type *qcmd = NULL; CDBG("=== vpe_do_tasklet start === \n"); spin_lock_irqsave(&vpe_ctrl->tasklet_lock, flags); qcmd = list_first_entry(&vpe_ctrl->tasklet_q, struct vpe_isr_queue_cmd_type, list); if (!qcmd) { spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags); return; } list_del(&qcmd->list); spin_unlock_irqrestore(&vpe_ctrl->tasklet_lock, flags); /* interrupt to be processed, *qcmd has the payload. */ if (qcmd->irq_status & 0x1) { if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_L) { CDBG("vpe left frame done.\n"); vpe_ctrl->output_type = 0; CDBG("vpe send out msg.\n"); orig_src_y = msm_camera_io_r(vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET); orig_src_cbcr = msm_camera_io_r(vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET); pyaddr = msm_camera_io_r(vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET); pcbcraddr = msm_camera_io_r(vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET); CDBG("%s: out_w = %d, out_h = %d\n", __func__, vpe_ctrl->out_w, vpe_ctrl->out_h); if ((vpe_ctrl->frame_pack == TOP_DOWN_FULL) || (vpe_ctrl->frame_pack == TOP_DOWN_HALF)) { msm_camera_io_w(pyaddr + (vpe_ctrl->out_w * vpe_ctrl->out_h), vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET); msm_camera_io_w(pcbcraddr + (vpe_ctrl->out_w * vpe_ctrl->out_h/2), vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET); } else if ((vpe_ctrl->frame_pack == SIDE_BY_SIDE_HALF) || (vpe_ctrl->frame_pack == SIDE_BY_SIDE_FULL)) { msm_camera_io_w(pyaddr + vpe_ctrl->out_w, vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET); msm_camera_io_w(pcbcraddr + vpe_ctrl->out_w, vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET); } else CDBG("%s: Invalid packing = %d\n", __func__, vpe_ctrl->frame_pack); vpe_send_msg_no_payload(MSG_ID_VPE_OUTPUT_ST_L); vpe_ctrl->state = VPE_STATE_INIT; kfree(qcmd); return; } else if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) { src_y = orig_src_y; src_cbcr = orig_src_cbcr; CDBG("%s: out_w = %d, out_h = %d\n", __func__, vpe_ctrl->out_w, vpe_ctrl->out_h); if ((vpe_ctrl->frame_pack == TOP_DOWN_FULL) || (vpe_ctrl->frame_pack == TOP_DOWN_HALF)) { pyaddr = msm_camera_io_r(vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET) - (vpe_ctrl->out_w * vpe_ctrl->out_h); } else if ((vpe_ctrl->frame_pack == SIDE_BY_SIDE_HALF) || (vpe_ctrl->frame_pack == SIDE_BY_SIDE_FULL)) { pyaddr = msm_camera_io_r(vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET) - vpe_ctrl->out_w; } else CDBG("%s: Invalid packing = %d\n", __func__, vpe_ctrl->frame_pack); pcbcraddr = vpe_ctrl->pcbcr_before_dis; } else { src_y = msm_camera_io_r(vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET); src_cbcr = msm_camera_io_r(vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET); pyaddr = msm_camera_io_r(vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET); pcbcraddr = msm_camera_io_r(vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET); } if (vpe_ctrl->dis_en) pcbcraddr = vpe_ctrl->pcbcr_before_dis; msm_camera_io_w(src_y, vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET); msm_camera_io_w(src_cbcr, vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET); temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET) & 0xFFFFFFFC; msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET); /* now pass this frame to msm_camera.c. */ if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) { CDBG("vpe send out R msg.\n"); vpe_send_outmsg(MSG_ID_VPE_OUTPUT_ST_R, pyaddr, pcbcraddr, pyaddr); } else if (vpe_ctrl->output_type == OUTPUT_TYPE_V) { CDBG("vpe send out V msg.\n"); vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr, pcbcraddr, pyaddr); } vpe_ctrl->output_type = 0; vpe_ctrl->state = VPE_STATE_INIT; /* put it back to idle. */ } kfree(qcmd); }
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); } }
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; } #if defined(CONFIG_HI542) irq2 = msm_camera_io_r(csiphybase + MIPI_CSIPHY_LNCK_CFG4_ADDR); pr_err("%s MIPI_CSIPHY_LNCK_CFG4_ADDR = 0x%x\n", __func__, irq2); msm_camera_io_w(0xc, csiphybase + MIPI_CSIPHY_LNCK_CFG4_ADDR); irq2 = msm_camera_io_r(csiphybase + MIPI_CSIPHY_LNCK_CFG4_ADDR); pr_err("%s 11 MIPI_CSIPHY_LNCK_CFG4_ADDR = 0x%x\n", __func__, irq2); #endif msleep(20); return rc; } static irqreturn_t msm_csiphy_irq(int irq_num, void *data) { uint32_t irq; int i; struct csiphy_device *csiphy_dev = data;
static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, struct msm_ispif_param_data *params) { int i, rc = 0; uint16_t cid_mask = 0; uint32_t intf_addr; 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; } for (i = 0; i < params->num; i++) { if (!msm_ispif_is_intf_valid(ispif->csid_version, params->entries[i].vfe_intf)) { pr_err("%s: invalid interface type\n", __func__); rc = -EINVAL; goto end; } } msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_DISABLE_FRAME_BOUNDARY, params); for (i = 0; i < params->num; i++) { cid_mask = msm_ispif_get_cids_mask_from_cfg(¶ms->entries[i]); vfe_intf = params->entries[i].vfe_intf; switch (params->entries[i].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; } /* todo_bug_fix? very bad. use readl_poll_timeout */ while ((msm_camera_io_r(ispif->base + intf_addr) & 0xF) != 0xF) CDBG("%s: Wait for %d Idle\n", __func__, params->entries[i].intftype); /* disable CIDs in CID_MASK register */ msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype, cid_mask, vfe_intf, 0); } end: return rc; }
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: VFE_WRITE: 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; if ((UINT_MAX - sizeof(*data_ptr) < reg_cfg_cmd->u.rw_info.reg_offset) || (resource_size(vfe_dev->vfe_mem) < reg_cfg_cmd->u.rw_info.reg_offset + sizeof(*data_ptr))) { pr_err("%s: VFE_WRITE_MB: Invalid length\n", __func__); return -EINVAL; } 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; if (resource_size(vfe_dev->vfe_mem) < reg_cfg_cmd->u.mask_info.reg_offset) 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; 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; } 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 ((UINT_MAX - reg_cfg_cmd->u.dmi_info.hi_tbl_offset < reg_cfg_cmd->u.dmi_info.len) || (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; }
static void vfe40_process_output_path_irq_1( struct axi_ctrl_t *axi_ctrl) { uint32_t ping_pong; uint32_t ch0_paddr, ch1_paddr, ch2_paddr; /* this must be snapshot main image output. */ uint8_t out_bool = 0; struct msm_free_buf *free_buf = NULL; free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ, VFE_MSG_OUTPUT_SECONDARY, axi_ctrl); out_bool = ((axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_RAW || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB) && (axi_ctrl->share_ctrl->vfe_capture_count <= 1)) || free_buf; if (out_bool) { ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase + VFE_BUS_PING_PONG_STATUS); /* Y channel */ ch0_paddr = vfe40_get_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out1.ch0); /* Chroma channel */ ch1_paddr = vfe40_get_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out1.ch1); ch2_paddr = vfe40_get_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out1.ch2); CDBG("%s ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n", __func__, ch0_paddr, ch1_paddr, ch2_paddr); if (free_buf) { /* Y channel */ vfe40_put_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out1.ch0, free_buf->ch_paddr[0]); /* Chroma channel */ vfe40_put_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out1.ch1, free_buf->ch_paddr[1]); if (free_buf->num_planes > 2) vfe40_put_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out1.ch2, free_buf->ch_paddr[2]); } if (axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_RAW || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB) axi_ctrl->share_ctrl->outpath.out1.capture_cnt--; vfe_send_outmsg(axi_ctrl, MSG_ID_OUTPUT_SECONDARY, ch0_paddr, ch1_paddr, ch2_paddr, axi_ctrl->share_ctrl->outpath.out1.image_mode); } else { axi_ctrl->share_ctrl->outpath.out1.frame_drop_cnt++; CDBG("path_irq_1 - no free buffer!\n"); } }
static void vfe40_process_output_path_irq_0( struct axi_ctrl_t *axi_ctrl) { uint32_t ping_pong; uint32_t ch0_paddr, ch1_paddr, ch2_paddr; uint8_t out_bool = 0; struct msm_free_buf *free_buf = NULL; free_buf = vfe40_check_free_buffer(VFE_MSG_OUTPUT_IRQ, VFE_MSG_OUTPUT_PRIMARY, axi_ctrl); /* we render frames in the following conditions: 1. Continuous mode and the free buffer is avaialable. 2. In snapshot shot mode, free buffer is not always available. when pending snapshot count is <=1, then no need to use free buffer. */ out_bool = ( (axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_RAW || axi_ctrl->share_ctrl->liveshot_state == VFE_STATE_STARTED || axi_ctrl->share_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED || axi_ctrl->share_ctrl->liveshot_state == VFE_STATE_STOPPED) && (axi_ctrl->share_ctrl->vfe_capture_count <= 1)) || free_buf; if (out_bool) { ping_pong = msm_camera_io_r(axi_ctrl->share_ctrl->vfebase + VFE_BUS_PING_PONG_STATUS); /* Channel 0*/ ch0_paddr = vfe40_get_ch_addr( ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out0.ch0); /* Channel 1*/ ch1_paddr = vfe40_get_ch_addr( ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out0.ch1); /* Channel 2*/ ch2_paddr = vfe40_get_ch_addr( ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out0.ch2); CDBG("output path 0, ch0 = 0x%x, ch1 = 0x%x, ch2 = 0x%x\n", ch0_paddr, ch1_paddr, ch2_paddr); if (free_buf) { /* Y channel */ vfe40_put_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out0.ch0, free_buf->ch_paddr[0]); /* Chroma channel */ vfe40_put_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out0.ch1, free_buf->ch_paddr[1]); if (free_buf->num_planes > 2) vfe40_put_ch_addr(ping_pong, axi_ctrl->share_ctrl->vfebase, axi_ctrl->share_ctrl->outpath.out0.ch2, free_buf->ch_paddr[2]); } if (axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB || axi_ctrl->share_ctrl->operation_mode == VFE_OUTPUTS_RAW || axi_ctrl->share_ctrl->liveshot_state == VFE_STATE_STOPPED) axi_ctrl->share_ctrl->outpath.out0.capture_cnt--; vfe_send_outmsg(axi_ctrl, MSG_ID_OUTPUT_PRIMARY, ch0_paddr, ch1_paddr, ch2_paddr, axi_ctrl->share_ctrl->outpath.out0.image_mode); if (axi_ctrl->share_ctrl->liveshot_state == VFE_STATE_STOPPED) axi_ctrl->share_ctrl->liveshot_state = VFE_STATE_IDLE; } else { axi_ctrl->share_ctrl->outpath.out0.frame_drop_cnt++; CDBG("path_irq_0 - no free buffer!\n"); } }
static int vfe40_config_axi( struct axi_ctrl_t *axi_ctrl, int mode, uint32_t *ao) { uint32_t *ch_info; uint32_t *axi_cfg = ao; /* Update the corresponding write masters for each output*/ ch_info = axi_cfg + V40_AXI_CFG_LEN; axi_ctrl->share_ctrl->outpath.out0.ch0 = 0x0000FFFF & *ch_info; axi_ctrl->share_ctrl->outpath.out0.ch1 = 0x0000FFFF & (*ch_info++ >> 16); axi_ctrl->share_ctrl->outpath.out0.ch2 = 0x0000FFFF & *ch_info; axi_ctrl->share_ctrl->outpath.out0.image_mode = 0x0000FFFF & (*ch_info++ >> 16); axi_ctrl->share_ctrl->outpath.out1.ch0 = 0x0000FFFF & *ch_info; axi_ctrl->share_ctrl->outpath.out1.ch1 = 0x0000FFFF & (*ch_info++ >> 16); axi_ctrl->share_ctrl->outpath.out1.ch2 = 0x0000FFFF & *ch_info; axi_ctrl->share_ctrl->outpath.out1.image_mode = 0x0000FFFF & (*ch_info++ >> 16); axi_ctrl->share_ctrl->outpath.out2.ch0 = 0x0000FFFF & *ch_info; axi_ctrl->share_ctrl->outpath.out2.ch1 = 0x0000FFFF & (*ch_info++ >> 16); axi_ctrl->share_ctrl->outpath.out2.ch2 = 0x0000FFFF & *ch_info++; switch (mode) { case OUTPUT_PRIM: axi_ctrl->share_ctrl->outpath.output_mode = VFE40_OUTPUT_MODE_PRIMARY; break; case OUTPUT_PRIM_ALL_CHNLS: axi_ctrl->share_ctrl->outpath.output_mode = VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS; break; case OUTPUT_PRIM|OUTPUT_SEC: axi_ctrl->share_ctrl->outpath.output_mode = VFE40_OUTPUT_MODE_PRIMARY; axi_ctrl->share_ctrl->outpath.output_mode |= VFE40_OUTPUT_MODE_SECONDARY; break; case OUTPUT_PRIM|OUTPUT_SEC_ALL_CHNLS: axi_ctrl->share_ctrl->outpath.output_mode = VFE40_OUTPUT_MODE_PRIMARY; axi_ctrl->share_ctrl->outpath.output_mode |= VFE40_OUTPUT_MODE_SECONDARY_ALL_CHNLS; break; case OUTPUT_PRIM_ALL_CHNLS|OUTPUT_SEC: axi_ctrl->share_ctrl->outpath.output_mode = VFE40_OUTPUT_MODE_PRIMARY_ALL_CHNLS; axi_ctrl->share_ctrl->outpath.output_mode |= VFE40_OUTPUT_MODE_SECONDARY; break; default: pr_err("%s Invalid AXI mode %d ", __func__, mode); return -EINVAL; } msm_camera_io_w(*ao, axi_ctrl->share_ctrl->vfebase + VFE_BUS_IO_FORMAT_CFG); msm_camera_io_memcpy(axi_ctrl->share_ctrl->vfebase + vfe40_cmd[VFE_CMD_AXI_OUT_CFG].offset, axi_cfg, vfe40_cmd[VFE_CMD_AXI_OUT_CFG].length - V40_AXI_CH_INF_LEN); msm_camera_io_w(*ch_info++, axi_ctrl->share_ctrl->vfebase + VFE_RDI0_CFG); if (msm_camera_io_r(axi_ctrl->share_ctrl->vfebase + V40_GET_HW_VERSION_OFF) == VFE40_HW_NUMBER) { msm_camera_io_w(*ch_info++, axi_ctrl->share_ctrl->vfebase + VFE_RDI1_CFG); msm_camera_io_w(*ch_info++, axi_ctrl->share_ctrl->vfebase + VFE_RDI2_CFG); } return 0; }
static int vpe_update_scaler_with_dis(struct video_crop_t *pcrop, struct dis_offset_type *dis_offset) { uint32_t out_ROI_width, out_ROI_height; uint32_t src_ROI_width, src_ROI_height; uint32_t rc = 0; /* default to no zoom. */ /* * 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, temp; int32_t src_x, src_y, src_xy; uint32_t yscale_filter_sel, xscale_filter_sel; uint32_t scale_unit_sel_x, scale_unit_sel_y; uint64_t numerator, denominator; int32_t zoom_dis_x, zoom_dis_y; CDBG("%s: pcrop->in2_w = %d, pcrop->in2_h = %d\n", __func__, pcrop->in2_w, pcrop->in2_h); CDBG("%s: pcrop->out2_w = %d, pcrop->out2_h = %d\n", __func__, pcrop->out2_w, pcrop->out2_h); if ((pcrop->in2_w >= pcrop->out2_w) && (pcrop->in2_h >= pcrop->out2_h)) { CDBG(" =======VPE no zoom needed, DIS is still enabled.\n"); temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET) & 0xfffffffc; msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET); /* no zoom, use dis offset directly. */ src_xy = dis_offset->dis_offset_y * (1<<16) + dis_offset->dis_offset_x; msm_camera_io_w(src_xy, vpe_device->vpebase + VPE_SRC_XY_OFFSET); CDBG("vpe_ctrl->in_h_w = 0x%x\n", vpe_ctrl->in_h_w); msm_camera_io_w(vpe_ctrl->in_h_w, vpe_device->vpebase + VPE_SRC_SIZE_OFFSET); return rc; } /* If fall through then scaler is needed.*/ CDBG("========VPE zoom needed + DIS enabled.\n"); /* assumption is both direction need zoom. this can be improved. */ temp = msm_camera_io_r(vpe_device->vpebase + VPE_OP_MODE_OFFSET) | 0x3; msm_camera_io_w(temp, vpe_device->vpebase + VPE_OP_MODE_OFFSET); zoom_dis_x = dis_offset->dis_offset_x * pcrop->in2_w / pcrop->out2_w; zoom_dis_y = dis_offset->dis_offset_y * pcrop->in2_h / pcrop->out2_h; src_x = zoom_dis_x + (pcrop->out2_w-pcrop->in2_w)/2; src_y = zoom_dis_y + (pcrop->out2_h-pcrop->in2_h)/2; out_ROI_width = vpe_ctrl->out_w; out_ROI_height = vpe_ctrl->out_h; src_ROI_width = out_ROI_width * pcrop->in2_w / pcrop->out2_w; src_ROI_height = out_ROI_height * pcrop->in2_h / pcrop->out2_h; /* clamp to output size. This is because along processing, we mostly do truncation, therefore dis_offset tends to be smaller values. The intention was to make sure that the offset does not exceed margin. But in the case it could result src_roi bigger, due to subtract a smaller value. */ CDBG("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_device->vpebase + VPE_SRC_SIZE_OFFSET); CDBG("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_device->vpebase + VPE_SRC_XY_OFFSET); CDBG("src_xy = 0x%x, src_roi=0x%x.\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); else if (scale_unit_sel_x == 0) { /* if using FIR scalar */ /* 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); else if (scale_unit_sel_y == 0) { /* if FIR scalar */ /* 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; CDBG("phase step x = %d, step y = %d.\n", phase_step_x, phase_step_y); CDBG("phase init x = %d, init y = %d.\n", phase_init_x, phase_init_y); msm_camera_io_w(phase_step_x, vpe_device->vpebase + VPE_SCALE_PHASEX_STEP_OFFSET); msm_camera_io_w(phase_step_y, vpe_device->vpebase + VPE_SCALE_PHASEY_STEP_OFFSET); msm_camera_io_w(phase_init_x, vpe_device->vpebase + VPE_SCALE_PHASEX_INIT_OFFSET); msm_camera_io_w(phase_init_y, vpe_device->vpebase + VPE_SCALE_PHASEY_INIT_OFFSET); return 1; }
static int msm_csid_init(struct csid_device *csid_dev, uint32_t *csid_version) { int rc = 0; if (!csid_version) { pr_err("%s:%d csid_version NULL\n", __func__, __LINE__); rc = -EINVAL; return rc; } if (csid_dev->csid_state == CSID_POWER_UP) { pr_err("%s: csid invalid state %d\n", __func__, csid_dev->csid_state); rc = -EINVAL; return rc; } csid_dev->base = ioremap(csid_dev->mem->start, resource_size(csid_dev->mem)); if (!csid_dev->base) { pr_err("%s csid_dev->base NULL\n", __func__); rc = -ENOMEM; return rc; } if (CSID_VERSION <= CSID_VERSION_V2) { rc = msm_camera_config_vreg(&csid_dev->pdev->dev, csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1); if (rc < 0) { pr_err("%s: regulator on failed\n", __func__); goto vreg_config_failed; } rc = msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_8960_vreg_info, ARRAY_SIZE(csid_8960_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1); if (rc < 0) { pr_err("%s: regulator enable failed\n", __func__); goto vreg_enable_failed; } rc = msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8960_clk_info, csid_dev->csid_clk, ARRAY_SIZE(csid_8960_clk_info), 1); if (rc < 0) { pr_err("%s: clock enable failed\n", __func__); goto clk_enable_failed; } } else if (CSID_VERSION >= CSID_VERSION_V3) { rc = msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1); if (rc < 0) { pr_err("%s: regulator on failed\n", __func__); goto vreg_config_failed; } rc = msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 1); if (rc < 0) { pr_err("%s: regulator enable failed\n", __func__); goto vreg_enable_failed; } rc = msm_cam_clk_enable(&csid_dev->pdev->dev, csid_8974_clk_info, csid_dev->csid_clk, ARRAY_SIZE(csid_8974_clk_info), 1); if (rc < 0) { pr_err("%s: clock enable failed\n", __func__); goto clk_enable_failed; } } CDBG("%s:%d called\n", __func__, __LINE__); csid_dev->hw_version = msm_camera_io_r(csid_dev->base + CSID_HW_VERSION_ADDR); CDBG("%s:%d called csid_dev->hw_version %x\n", __func__, __LINE__, csid_dev->hw_version); *csid_version = csid_dev->hw_version; init_completion(&csid_dev->reset_complete); enable_irq(csid_dev->irq->start); msm_csid_reset(csid_dev); csid_dev->csid_state = CSID_POWER_UP; return rc; clk_enable_failed: if (CSID_VERSION <= CSID_VERSION_V2) { 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); } else if (CSID_VERSION >= CSID_VERSION_V3) { msm_camera_enable_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } vreg_enable_failed: if (CSID_VERSION <= CSID_VERSION_V2) { 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_VERSION >= CSID_VERSION_V3) { msm_camera_config_vreg(&csid_dev->pdev->dev, csid_vreg_info, ARRAY_SIZE(csid_vreg_info), NULL, 0, &csid_dev->csi_vdd, 0); } vreg_config_failed: iounmap(csid_dev->base); csid_dev->base = NULL; return rc; }
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_V4L2) 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_V4L2) 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; }
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; }
/* 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_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); //LGE_CHANGE_S, HI544 line-noise issue fix, 2014-06-12, [email protected], CASE#01569989 if(csiphy_dev->pdev->id == 0) { //main camera #if defined (CONFIG_HI544) || defined (CONFIG_HI841) || \ defined(CONFIG_MACH_MSM8916_Y50_TRF_US) || \ defined(CONFIG_MACH_MSM8916_Y50C_TRF_US) || \ defined(CONFIG_MACH_MSM8916_C50_GLOBAL_COM) || \ defined(CONFIG_MACH_MSM8916_C50_TRF_US) || \ defined(CONFIG_MACH_MSM8916_C50_MPCS_US) || \ defined(CONFIG_MACH_MSM8916_C50_TMO_US) || \ defined(CONFIG_MACH_MSM8916_C50_SPR_US) || \ defined(CONFIG_MACH_MSM8916_C50_CRK_US) || \ defined(CONFIG_MACH_MSM8916_C30_TRF_US) || \ defined(CONFIG_MACH_MSM8916_C30C_TRF_US) || \ defined(CONFIG_MACH_MSM8916_C50DS_GLOBAL_COM) || \ defined(CONFIG_MACH_MSM8916_C50N_GLOBAL_COM) if(csiphy_dev->hw_version >= CSIPHY_VERSION_V30) { msm_camera_io_w(0xC, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnn_cfg4_addr + 0x40*j); } #endif } else { //sub camera #if defined (CONFIG_HI191) if(csiphy_dev->hw_version >= CSIPHY_VERSION_V30) { msm_camera_io_w(0xC, csiphybase + csiphy_dev->ctrl_reg->csiphy_reg. mipi_csiphy_lnn_cfg4_addr + 0x40*j); } #endif } //LGE_CHANGE_E, HI544 line-noise issue fix, 2014-06-12, [email protected], CASE#01569989 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; }