/* * 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; }
/* * isp_csi2_isr - CSI2 interrupt handling. * * Return -EIO on Transmission error */ int isp_csi2_isr(struct isp_csi2_device *csi2) { u32 csi2_irqstatus, cpxio1_irqstatus; struct isp_device *isp = csi2->isp; int retval = 0; if (!csi2->available) return -ENODEV; csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS); isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS); /* Failure Cases */ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ) { cpxio1_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_PHY_IRQSTATUS); isp_reg_writel(isp, cpxio1_irqstatus, csi2->regs1, ISPCSI2_PHY_IRQSTATUS); dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ " "%x\n", cpxio1_irqstatus); retval = -EIO; } if (csi2_irqstatus & (ISPCSI2_IRQSTATUS_OCP_ERR_IRQ | ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ | ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ | ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ | ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ)) { dev_dbg(isp->dev, "CSI2 Err:" " OCP:%d," " Short_pack:%d," " ECC:%d," " CPXIO2:%d," " FIFO_OVF:%d," "\n", (csi2_irqstatus & ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) ? 1 : 0, (csi2_irqstatus & ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ) ? 1 : 0, (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ) ? 1 : 0, (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0, (csi2_irqstatus & ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0); retval = -EIO; } if (isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping)) return 0; /* Successful cases */ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0)) isp_csi2_isr_ctx(csi2, &csi2->contexts[0]); if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ) dev_dbg(isp->dev, "CSI2: ECC correction done\n"); return retval; }
/* * ispccp2_phyif_config - Initialize CCP2 phy interface config * @ccp2: Pointer to ISP CCP2 device * @config: CCP2 platform data * * Configure the CCP2 physical interface module from platform data. * * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success. */ static int ispccp2_phyif_config(struct isp_ccp2_device *ccp2, const struct isp_ccp2_platform_data *pdata) { struct isp_device *isp = to_isp_device(ccp2); u32 val; /* CCP2B mode */ val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) | ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE; /* Data/strobe physical layer */ BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK, pdata->phy_layer); BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK, pdata->strobe_clk_pol); isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); if (!(val & ISPCCP2_CTRL_MODE)) { if (pdata->ccp2_mode) dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n"); if (pdata->phy_layer == ISPCCP2_CTRL_PHY_SEL_STROBE) /* Strobe mode requires CCP2 */ return -EIO; } return 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; }
/* * Returns zero if the CCDC is idle and the image has been written to * memory, too. */ int ispccdc_sbl_busy(void) { return ispccdc_busy() | (isp_reg_readl(OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_0) & ISPSBL_CCDC_WR_0_DATA_READY) | (isp_reg_readl(OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_1) & ISPSBL_CCDC_WR_0_DATA_READY) | (isp_reg_readl(OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_2) & ISPSBL_CCDC_WR_0_DATA_READY) | (isp_reg_readl(OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_3) & ISPSBL_CCDC_WR_0_DATA_READY); }
void __ispresizer_enable(int enable) { int val; DPRINTK_ISPRESZ("+ispresizer_enable()+\n"); if (enable) { val = (isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & 0x2) | ISPRSZ_PCR_ENABLE; } else { val = isp_reg_readl(OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & ~ISPRSZ_PCR_ENABLE; } isp_reg_writel(val, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR); DPRINTK_ISPRESZ("+ispresizer_enable()-\n"); }
/* * ispresizer_busy - Checks if ISP resizer is busy. * * Returns busy field from ISPRSZ_PCR register. */ int ispresizer_busy(struct isp_res_device *res) { struct isp_device *isp = to_isp_device(res); return isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & ISPRSZ_PCR_BUSY; }
/* * ispresizer_set_ratio - Setup horizontal and vertical resizing value * @isp_res: Device context. * @ratio: Structure for ratio parameters. * * Resizing range from 64 to 1024 */ static void ispresizer_set_ratio(struct isp_res_device *res, const struct resizer_ratio *ratio) { struct isp_device *isp = to_isp_device(res); const u16 *h_filter, *v_filter; u32 rgval = 0; rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) & ~(ISPRSZ_CNT_HRSZ_MASK | ISPRSZ_CNT_VRSZ_MASK); rgval |= ((ratio->horz - 1) << ISPRSZ_CNT_HRSZ_SHIFT) & ISPRSZ_CNT_HRSZ_MASK; rgval |= ((ratio->vert - 1) << ISPRSZ_CNT_VRSZ_SHIFT) & ISPRSZ_CNT_VRSZ_MASK; isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT); /* prepare horizontal filter coefficients */ if (ratio->horz > MID_RESIZE_VALUE) h_filter = &filter_coefs.h_filter_coef_7tap[0]; else h_filter = &filter_coefs.h_filter_coef_4tap[0]; /* prepare vertical filter coefficients */ if (ratio->vert > MID_RESIZE_VALUE) v_filter = &filter_coefs.v_filter_coef_7tap[0]; else v_filter = &filter_coefs.v_filter_coef_4tap[0]; ispresizer_set_filters(res, h_filter, v_filter); }
void isp_reg_and_or(enum isp_mem_resources mmio_range, u32 reg, u32 and_bits, u32 or_bits) { u32 v = isp_reg_readl(mmio_range, reg); isp_reg_writel((v & and_bits) | or_bits, mmio_range, reg); }
/** * ispresizer_is_enabled - Checks if ISP resizer is enable. * * Returns busy field from ISPRSZ_PCR register. **/ int ispresizer_is_enabled(struct isp_res_device *isp_res) { struct device *dev = to_device(isp_res); return isp_reg_readl(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & ISPRSZ_PCR_ENABLE; }
int isp_af_busy(struct isp_af_device *af) { struct isp_device *isp = to_isp_device(af); return isp_reg_readl(isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR) & ISPH3A_PCR_BUSYAF; }
/* * csi2_timing_config - CSI2 timing configuration. * @timing: csi2_timing_cfg structure */ static void csi2_timing_config(struct isp_device *isp, struct isp_csi2_device *csi2, struct isp_csi2_timing_cfg *timing) { u32 reg; reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_TIMING); if (timing->force_rx_mode) reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum); else reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum); if (timing->stop_state_16x) reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum); else reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum); if (timing->stop_state_4x) reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum); else reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum); reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(timing->ionum); reg |= timing->stop_state_counter << ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(timing->ionum); isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_TIMING); }
/* * csi2_ctx_enable - Enable specified CSI2 context * @ctxnum: Context number, valid between 0 and 7 values. * @enable: enable * */ static void csi2_ctx_enable(struct isp_device *isp, struct isp_csi2_device *csi2, u8 ctxnum, u8 enable) { struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[ctxnum]; unsigned int skip = 0; u32 reg; reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum)); if (enable) { if (csi2->frame_skip) skip = csi2->frame_skip; else if (csi2->output & CSI2_OUTPUT_MEMORY) skip = 1; reg &= ~ISPCSI2_CTX_CTRL1_COUNT_MASK; reg |= ISPCSI2_CTX_CTRL1_COUNT_UNLOCK | (skip << ISPCSI2_CTX_CTRL1_COUNT_SHIFT) | ISPCSI2_CTX_CTRL1_CTX_EN; } else { reg &= ~ISPCSI2_CTX_CTRL1_CTX_EN; } isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum)); ctx->enabled = enable; }
/** * isph3a_aewb_update_regs - Helper function to update h3a registers. **/ static void isph3a_aewb_update_regs(struct isp_h3a_device *isp_h3a) { u32 pcr; if (!isp_h3a->update) return; pcr = isp_reg_readl(isp_h3a->dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); isp_reg_writel(isp_h3a->dev, (pcr & ~ISPH3A_PCR_AEW_MASK) | (isp_h3a->regs.pcr & ~ISPH3A_PCR_AEW_EN), OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); if (!isp_h3a->aewb_config_local.aewb_enable) return; if (isph3a_aewb_busy(isp_h3a)) { isp_reg_writel(isp_h3a->dev, (pcr & ~ISPH3A_PCR_AEW_MASK) | isp_h3a->regs.pcr, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); return; } isp_reg_writel(isp_h3a->dev, isp_h3a->regs.win1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1); isp_reg_writel(isp_h3a->dev, isp_h3a->regs.start, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINSTART); isp_reg_writel(isp_h3a->dev, isp_h3a->regs.blk, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK); isp_reg_writel(isp_h3a->dev, isp_h3a->regs.subwin, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWSUBWIN); isp_reg_writel(isp_h3a->dev, (pcr & ~ISPH3A_PCR_AEW_MASK) | isp_h3a->regs.pcr, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); isp_h3a->update = 0; }
/* * csi2_recv_config - CSI2 receiver module configuration. * @currctrl: isp_csi2_ctrl_cfg structure * */ static void csi2_recv_config(struct isp_device *isp, struct isp_csi2_device *csi2, struct isp_csi2_ctrl_cfg *currctrl) { u32 reg; reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTRL); if (currctrl->frame_mode) reg |= ISPCSI2_CTRL_FRAME; else reg &= ~ISPCSI2_CTRL_FRAME; if (currctrl->vp_clk_enable) reg |= ISPCSI2_CTRL_VP_CLK_EN; else reg &= ~ISPCSI2_CTRL_VP_CLK_EN; if (currctrl->vp_only_enable) reg |= ISPCSI2_CTRL_VP_ONLY_EN; else reg &= ~ISPCSI2_CTRL_VP_ONLY_EN; reg &= ~ISPCSI2_CTRL_VP_OUT_CTRL_MASK; reg |= currctrl->vp_out_ctrl << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT; if (currctrl->ecc_enable) reg |= ISPCSI2_CTRL_ECC_EN; else reg &= ~ISPCSI2_CTRL_ECC_EN; isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTRL); }
int isp_af_busy(struct isp_af_device *isp_af) { struct device *dev = to_device(isp_af); return isp_reg_readl(dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR) & ISPH3A_PCR_BUSYAF; }
int isph3a_aewb_busy(struct isp_h3a_device *isp_h3a) { struct device *dev = to_device(isp_h3a); return isp_reg_readl(dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR) & ISPH3A_PCR_BUSYAEAWB; }
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; }
static void __ispstat_pcr_enable(struct ispstat *stat, u8 pcr_enable) { u32 pcr = isp_reg_readl(stat->isp, stat->pcr->base, stat->pcr->offset); if (pcr_enable) pcr |= stat->pcr->enable; else pcr &= ~stat->pcr->enable; isp_reg_writel(stat->isp, pcr, stat->pcr->base, stat->pcr->offset); }
/** * ispresizer_enable - Enables the resizer module. * @enable: 1 - Enable, 0 - Disable * * Client should configure all the sub modules in resizer before this. **/ void ispresizer_enable(struct isp_res_device *isp_res, int enable) { struct device *dev = to_device(isp_res); int val; if (enable) { #ifdef CONFIG_VIDEO_OMAP34XX_ISP_DEBUG_FS struct isp_device *isp = to_isp_device(isp_res); if (isp->dfs_resz) ispresz_dfs_dump(isp); #endif val = (isp_reg_readl(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & ISPRSZ_PCR_ONESHOT) | ISPRSZ_PCR_ENABLE; } else { val = isp_reg_readl(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) & ~ISPRSZ_PCR_ENABLE; } isp_reg_writel(dev, val, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR); }
void ispaf_dfs_dump(struct isp_device *isp) { if (ispaf_dfs_buff != NULL) { ispaf_dfs_offs = ispaf_dfs_buff; ispaf_dfs_offs += sprintf(ispaf_dfs_offs, "PAXH/2: %4d\n", (isp_reg_readl(isp->dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1) & ISPH3A_AF_PAXH_MASK) >> ISPH3A_AF_PAXH_SHIFT); ispaf_dfs_offs += sprintf(ispaf_dfs_offs, "PAXW/2: %4d\n", (isp_reg_readl(isp->dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1) & ISPH3A_AF_PAXW_MASK) >> ISPH3A_AF_PAXW_SHIFT); ispaf_dfs_offs += sprintf(ispaf_dfs_offs, "PAXHC: %4d\n", (isp_reg_readl(isp->dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2) & ISPH3A_AF_PAXHC_MASK) >> ISPH3A_AF_PAXHC_SHIFT); ispaf_dfs_offs += sprintf(ispaf_dfs_offs, "PAXVC: %4d\n", (isp_reg_readl(isp->dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2) & ISPH3A_AF_PAXVC_MASK) >> ISPH3A_AF_PAXVC_SHIFT); ispaf_dfs_offs += sprintf(ispaf_dfs_offs, "PAXSH: %4d\n", (isp_reg_readl(isp->dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAXSTART) & ISPH3A_AF_PAXSH_MASK) >> ISPH3A_AF_PAXSH_SHIFT); ispaf_dfs_offs += sprintf(ispaf_dfs_offs, "PAXSV: %4d\n", (isp_reg_readl(isp->dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAXSTART) & ISPH3A_AF_PAXSV_MASK) >> ISPH3A_AF_PAXSV_SHIFT); }
/* * ispresizer_set_phase - Setup horizontal and vertical starting phase * @isp_res: Device context. * @h_phase: horizontal phase parameters. * @v_phase: vertical phase parameters. * * Horizontal and vertical phase range is 0 to 7 */ static void ispresizer_set_phase(struct isp_res_device *res, u32 h_phase, u32 v_phase) { struct isp_device *isp = to_isp_device(res); u32 rgval = 0; rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) & ~(ISPRSZ_CNT_HSTPH_MASK | ISPRSZ_CNT_VSTPH_MASK); rgval |= (h_phase << ISPRSZ_CNT_HSTPH_SHIFT) & ISPRSZ_CNT_HSTPH_MASK; rgval |= (v_phase << ISPRSZ_CNT_VSTPH_SHIFT) & ISPRSZ_CNT_VSTPH_MASK; isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT); }
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; }
/** * ispresizer_set_ratio - Setup horizontal and vertical resizing value * @dev: Device context. * @h_ratio: Horizontal ratio. * @v_ratio: Vertical ratio. * * Resizing range from 64 to 1024 */ static inline void ispresizer_set_ratio(struct device *dev, u16 h_ratio, u16 v_ratio) { u32 rgval; rgval = isp_reg_readl(dev, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) & ~(ISPRSZ_CNT_HRSZ_MASK | ISPRSZ_CNT_VRSZ_MASK); rgval |= ((h_ratio - 1) << ISPRSZ_CNT_HRSZ_SHIFT) & ISPRSZ_CNT_HRSZ_MASK; rgval |= ((v_ratio - 1) << ISPRSZ_CNT_VRSZ_SHIFT) & ISPRSZ_CNT_VRSZ_MASK; isp_reg_writel(dev, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT); dev_dbg(dev, "%s: Ratio: H=%d V=%d\n", __func__, h_ratio, v_ratio); }
static void __isp_af_enable(struct isp_af_device *isp_af, int enable) { struct device *dev = to_device(isp_af); unsigned int pcr; pcr = isp_reg_readl(dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); /* Set AF_EN bit in PCR Register */ if (enable) pcr |= AF_EN; else pcr &= ~AF_EN; isp_reg_writel(dev, pcr, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); }
/* * ispccp2_vp_config - Initialize CCP2 video port interface. * @ccp2: Pointer to ISP CCP2 device * @vpclk_div: Video port divisor * * Configure the CCP2 video port with the given clock divisor. The valid divisor * values depend on the ISP revision: * * - revision 1.0 and 2.0 1 to 4 * - revision 15.0 1 to 65536 * * The exact divisor value used might differ from the requested value, as ISP * revision 15.0 represent the divisor by 65536 divided by an integer. */ static void ispccp2_vp_config(struct isp_ccp2_device *ccp2, unsigned int vpclk_div) { struct isp_device *isp = to_isp_device(ccp2); u32 val; /* ISPCCP2_CTRL Video port */ val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); val |= ISPCCP2_CTRL_VP_ONLY_EN; /* Disable the memory write port */ if (isp->revision == ISP_REVISION_15_0) { vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 65536); vpclk_div = min(ISPCCP2_VPCLK_FRACDIV / vpclk_div, 65535U); BIT_SET(val, ISPCCP2_CTRL_VPCLK_DIV_SHIFT, ISPCCP2_CTRL_VPCLK_DIV_MASK, vpclk_div); } else {
/** * ispresizer_request - Reserves the Resizer module. * * Allows only one user at a time. * * Returns 0 if successful, or -EBUSY if resizer module was already requested. **/ int ispresizer_request() { mutex_lock(&ispres_obj.ispres_mutex); if (!ispres_obj.res_inuse) { ispres_obj.res_inuse = 1; mutex_unlock(&ispres_obj.ispres_mutex); isp_reg_writel(isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL) | ISPCTRL_SBL_WR0_RAM_EN | ISPCTRL_RSZ_CLK_EN, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL); return 0; } else { mutex_unlock(&ispres_obj.ispres_mutex); printk(KERN_ERR "ISP_ERR : Resizer Module Busy\n"); return -EBUSY; } }
void isp_dfs_dump(struct isp_device *isp) { u32 idx; if (isp_dfs_buff != NULL) { isp_dfs_offs = isp_dfs_buff; for (idx = 0; idx < ARRAY_SIZE(isp_dfs_lables); idx++) { isp_dfs_offs += sprintf(isp_dfs_offs, "%s", isp_dfs_lables[idx].ascii_reg); isp_dfs_offs += sprintf(isp_dfs_offs, "0x%08X\n", isp_reg_readl(isp->dev, OMAP3_ISP_IOMEM_MAIN, isp_dfs_lables[idx]\ .reg_offset)); } } }
void __isph3a_aewb_enable(struct isp_h3a_device *isp_h3a, u8 enable) { struct device *dev = to_device(isp_h3a); u32 pcr = isp_reg_readl(dev, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); if (enable) { #ifdef CONFIG_VIDEO_OMAP34XX_ISP_DEBUG_FS struct isp_device *isp = to_isp_device(isp_h3a); if (isp->dfs_h3a) isph3a_dfs_dump(isp); #endif pcr |= ISPH3A_PCR_AEW_EN; } else { pcr &= ~ISPH3A_PCR_AEW_EN; } isp_reg_writel(dev, pcr, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR); }
/* * 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; } } }