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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
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));
	}
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
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));
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
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;
};
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
0
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);
	}
}
Ejemplo n.º 19
0
            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;
Ejemplo n.º 20
0
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(&params->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;
}
Ejemplo n.º 21
0
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;
    }
Ejemplo n.º 22
0
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");
	}
}
Ejemplo n.º 23
0
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");
	}
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 28
0
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;
}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
0
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;
    }