Ejemplo n.º 1
0
static void hist_enable(struct ispstat *hist, int enable)
{
    if (enable) {
        isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
                    ISPHIST_PCR_ENABLE);
        isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
                    ISPCTRL_HIST_CLK_EN);
    } else {
        isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
                    ISPHIST_PCR_ENABLE);
        isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
                    ISPCTRL_HIST_CLK_EN);
    }
}
Ejemplo n.º 2
0
/*
 * ispccp2_if_enable - Enable CCP2 interface.
 * @ccp2: pointer to ISP CCP2 device
 * @enable: enable/disable flag
 */
static void ispccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
{
	struct isp_device *isp = to_isp_device(ccp2);
	struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
	int i;

	if (enable && ccp2->vdds_csib)
		regulator_enable(ccp2->vdds_csib);

	/* Enable/Disable all the LCx channels */
	for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
		isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i),
				ISPCCP2_LCx_CTRL_CHAN_EN,
				enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0);

	/* Enable/Disable ccp2 interface in ccp2 mode */
	isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
			ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,
			enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);

	/* For frame count propagation */
	if (pipe->do_propagation) {
		/* We may want the Frame Start IRQ from LC0 */
		if (enable)
			isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2,
				    ISPCCP2_LC01_IRQENABLE,
				    ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
		else
			isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCP2,
				    ISPCCP2_LC01_IRQENABLE,
				    ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
	}
	if (!enable && ccp2->vdds_csib)
		regulator_disable(ccp2->vdds_csib);
}
Ejemplo n.º 3
0
static int hist_buf_pio(struct ispstat *hist)
{
    struct isp_device *isp = hist->isp;
    u32 *buf = hist->active_buf->virt_addr;
    unsigned int i;

    if (!buf) {
        dev_dbg(isp->dev, "hist: invalid PIO buffer address\n");
        hist_reset_mem(hist);
        return STAT_NO_BUF;
    }

    isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);

    isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);

    for (i = hist->buf_size / 16; i > 0; i--) {
        *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
        *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
        *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
        *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
    }
    isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
                ISPHIST_CNT_CLEAR);

    return STAT_BUF_DONE;
}
Ejemplo n.º 4
0
Archivo: isphist.c Proyecto: 7799/linux
/*
 * hist_reset_mem - clear Histogram memory before start stats engine.
 */
static void hist_reset_mem(struct ispstat *hist)
{
	struct isp_device *isp = hist->isp;
	struct omap3isp_hist_config *conf = hist->priv;
	unsigned int i;

	isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);

	/*
	 * By setting it, the histogram internal buffer is being cleared at the
	 * same time it's being read. This bit must be cleared afterwards.
	 */
	isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);

	/*
	 * We'll clear 4 words at each iteration for optimization. It avoids
	 * 3/4 of the jumps. We also know HIST_MEM_SIZE is divisible by 4.
	 */
	for (i = OMAP3ISP_HIST_MEM_SIZE / 4; i > 0; i--) {
		isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
		isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
		isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
		isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
	}
	isp_reg_clr(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);

	hist->wait_acc_frames = conf->num_acc_frames;
}
Ejemplo n.º 5
0
static int hist_buf_dma(struct ispstat *hist)
{
	dma_addr_t dma_addr = hist->active_buf->dma_addr;
	struct dma_async_tx_descriptor *tx;
	struct dma_slave_config cfg;
	dma_cookie_t cookie;
	int ret;

	if (unlikely(!dma_addr)) {
		dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n");
		goto error;
	}

	isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
	isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
		    ISPHIST_CNT_CLEAR);
	omap3isp_flush(hist->isp);

	memset(&cfg, 0, sizeof(cfg));
	cfg.src_addr = hist->isp->mmio_hist_base_phys + ISPHIST_DATA;
	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	cfg.src_maxburst = hist->buf_size / 4;

	ret = dmaengine_slave_config(hist->dma_ch, &cfg);
	if (ret < 0) {
		dev_dbg(hist->isp->dev,
			"hist: DMA slave configuration failed\n");
		goto error;
	}

	tx = dmaengine_prep_slave_single(hist->dma_ch, dma_addr,
					 hist->buf_size, DMA_DEV_TO_MEM,
					 DMA_CTRL_ACK);
	if (tx == NULL) {
		dev_dbg(hist->isp->dev,
			"hist: DMA slave preparation failed\n");
		goto error;
	}

	tx->callback = hist_dma_cb;
	tx->callback_param = hist;
	cookie = tx->tx_submit(tx);
	if (dma_submit_error(cookie)) {
		dev_dbg(hist->isp->dev, "hist: DMA submission failed\n");
		goto error;
	}

	dma_async_issue_pending(hist->dma_ch);

	return STAT_BUF_WAITING_DMA;

error:
	hist_reset_mem(hist);
	return STAT_NO_BUF;
}
Ejemplo n.º 6
0
Archivo: isphist.c Proyecto: 7799/linux
static void hist_enable(struct ispstat *hist, int enable)
{
	if (enable) {
		isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
			    ISPHIST_PCR_ENABLE);
		omap3isp_subclk_enable(hist->isp, OMAP3_ISP_SUBCLK_HIST);
	} else {
		isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
			    ISPHIST_PCR_ENABLE);
		omap3isp_subclk_disable(hist->isp, OMAP3_ISP_SUBCLK_HIST);
	}
}
Ejemplo n.º 7
0
/*
 * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
 * @enable: Enable/disable CSI2 Context interrupts
 */
static void csi2_irq_ctx_set(struct isp_device *isp,
                             struct isp_csi2_device *csi2, int enable)
{
    int i;

    for (i = 0; i < 8; i++) {
        isp_reg_writel(isp, ISPCSI2_CTX_IRQSTATUS_FE_IRQ, csi2->regs1,
                       ISPCSI2_CTX_IRQSTATUS(i));
        if (enable)
            isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
                        ISPCSI2_CTX_IRQSTATUS_FE_IRQ);
        else
            isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
                        ISPCSI2_CTX_IRQSTATUS_FE_IRQ);
    }
}
Ejemplo n.º 8
0
/*
 * ispccp2_reset - Reset the CCP2
 * @ccp2: pointer to ISP CCP2 device
 */
static void ispccp2_reset(struct isp_ccp2_device *ccp2)
{
	struct isp_device *isp = to_isp_device(ccp2);
	int i = 0;

	/* Reset the CSI1/CCP2B and wait for reset to complete */
	isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG,
		    ISPCCP2_SYSCONFIG_SOFT_RESET);
	while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) &
		 ISPCCP2_SYSSTATUS_RESET_DONE)) {
		udelay(10);
		if (i++ > 10) {  /* try read 10 times */
			dev_warn(isp->dev,
				"omap3_isp: timeout waiting for ccp2 reset\n");
			break;
		}
	}
}
Ejemplo n.º 9
0
static void ccp2_reset(struct isp_ccp2_device *ccp2)
{
    struct isp_device *isp = to_isp_device(ccp2);
    int i = 0;


    isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG,
                ISPCCP2_SYSCONFIG_SOFT_RESET);
    while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) &
             ISPCCP2_SYSSTATUS_RESET_DONE)) {
        udelay(10);
        if (i++ > 10) {
            dev_warn(isp->dev,
                     "omap3_isp: timeout waiting for ccp2 reset\n");
            break;
        }
    }
}
Ejemplo n.º 10
0
/*
 * isp_csi2_irq_ctx_set - Enables CSI2 Context IRQs.
 * @enable: Enable/disable CSI2 Context interrupts
 */
static void isp_csi2_irq_ctx_set(struct isp_device *isp,
				 struct isp_csi2_device *csi2, int enable)
{
	u32 reg = ISPCSI2_CTX_IRQSTATUS_FE_IRQ;
	int i;

	if (csi2->use_fs_irq)
		reg |= ISPCSI2_CTX_IRQSTATUS_FS_IRQ;

	for (i = 0; i < 8; i++) {
		isp_reg_writel(isp, reg, csi2->regs1,
			       ISPCSI2_CTX_IRQSTATUS(i));
		if (enable)
			isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
				    reg);
		else
			isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
				    reg);
	}
}
Ejemplo n.º 11
0
static void hist_reset_mem(struct ispstat *hist)
{
    struct isp_device *isp = hist->isp;
    struct omap3isp_hist_config *conf = hist->priv;
    unsigned int i;

    isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);

    isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);

    for (i = OMAP3ISP_HIST_MEM_SIZE / 4; i > 0; i--) {
        isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
        isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
        isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
        isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
    }
    isp_reg_clr(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);

    hist->wait_acc_frames = conf->num_acc_frames;
}
Ejemplo n.º 12
0
static int hist_buf_dma(struct ispstat *hist)
{
    dma_addr_t dma_addr = hist->active_buf->dma_addr;

    if (unlikely(!dma_addr)) {
        dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n");
        hist_reset_mem(hist);
        return STAT_NO_BUF;
    }

    isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
    isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
                ISPHIST_CNT_CLEAR);
    omap3isp_flush(hist->isp);
    hist->dma_config.dst_start = dma_addr;
    hist->dma_config.elem_count = hist->buf_size / sizeof(u32);
    omap_set_dma_params(hist->dma_ch, &hist->dma_config);

    omap_start_dma(hist->dma_ch);

    return STAT_BUF_WAITING_DMA;
}
Ejemplo n.º 13
0
Archivo: isphist.c Proyecto: 7799/linux
static int hist_buf_pio(struct ispstat *hist)
{
	struct isp_device *isp = hist->isp;
	u32 *buf = hist->active_buf->virt_addr;
	unsigned int i;

	if (!buf) {
		dev_dbg(isp->dev, "hist: invalid PIO buffer address\n");
		hist_reset_mem(hist);
		return STAT_NO_BUF;
	}

	isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);

	/*
	 * By setting it, the histogram internal buffer is being cleared at the
	 * same time it's being read. This bit must be cleared just after all
	 * data is acquired.
	 */
	isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);

	/*
	 * We'll read 4 times a 4-bytes-word at each iteration for
	 * optimization. It avoids 3/4 of the jumps. We also know buf_size is
	 * divisible by 16.
	 */
	for (i = hist->buf_size / 16; i > 0; i--) {
		*buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
		*buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
		*buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
		*buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
	}
	isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
		    ISPHIST_CNT_CLEAR);

	return STAT_BUF_DONE;
}
Ejemplo n.º 14
0
static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
{
    struct isp_device *isp = to_isp_device(ccp2);
    struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
    int i;

    if (enable && ccp2->vdds_csib)
        regulator_enable(ccp2->vdds_csib);


    for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
        isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i),
                        ISPCCP2_LCx_CTRL_CHAN_EN,
                        enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0);


    isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
                    ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,
                    enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);


    if (pipe->do_propagation) {

        if (enable)
            isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2,
                        ISPCCP2_LC01_IRQENABLE,
                        ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
        else
            isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCP2,
                        ISPCCP2_LC01_IRQENABLE,
                        ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
    }

    if (!enable && ccp2->vdds_csib)
        regulator_disable(ccp2->vdds_csib);
}
Ejemplo n.º 15
0
/*
 * omap3isp_csi2_reset - Resets the CSI2 module.
 *
 * Must be called with the phy lock held.
 *
 * Returns 0 if successful, or -EBUSY if power command didn't respond.
 */
int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
{
    struct isp_device *isp = csi2->isp;
    u8 soft_reset_retries = 0;
    u32 reg;
    int i;

    if (!csi2->available)
        return -ENODEV;

    if (csi2->phy->phy_in_use)
        return -EBUSY;

    isp_reg_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
                ISPCSI2_SYSCONFIG_SOFT_RESET);

    do {
        reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_SYSSTATUS) &
              ISPCSI2_SYSSTATUS_RESET_DONE;
        if (reg == ISPCSI2_SYSSTATUS_RESET_DONE)
            break;
        soft_reset_retries++;
        if (soft_reset_retries < 5)
            udelay(100);
    } while (soft_reset_retries < 5);

    if (soft_reset_retries == 5) {
        dev_err(isp->dev, "CSI2: Soft reset try count exceeded!\n");
        return -EBUSY;
    }

    if (isp->revision == ISP_REVISION_15_0)
        isp_reg_set(isp, csi2->regs1, ISPCSI2_PHY_CFG,
                    ISPCSI2_PHY_CFG_RESET_CTRL);

    i = 100;
    do {
        reg = isp_reg_readl(isp, csi2->phy->phy_regs, ISPCSIPHY_REG1)
              & ISPCSIPHY_REG1_RESET_DONE_CTRLCLK;
        if (reg == ISPCSIPHY_REG1_RESET_DONE_CTRLCLK)
            break;
        udelay(100);
    } while (--i > 0);

    if (i == 0) {
        dev_err(isp->dev,
                "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
        return -EBUSY;
    }

    if (isp->autoidle)
        isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
                        ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
                        ISPCSI2_SYSCONFIG_AUTO_IDLE,
                        ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART |
                        ((isp->revision == ISP_REVISION_15_0) ?
                         ISPCSI2_SYSCONFIG_AUTO_IDLE : 0));
    else
        isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
                        ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
                        ISPCSI2_SYSCONFIG_AUTO_IDLE,
                        ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO);

    return 0;
}