Lines Matching +full:isp +full:- +full:0

1 // SPDX-License-Identifier: GPL-2.0-only
5 * TI OMAP3 ISP - Histogram module
21 #include "isp.h"
28 * hist_reset_mem - clear Histogram memory before start stats engine.
32 struct isp_device *isp = hist->isp; in hist_reset_mem() local
33 struct omap3isp_hist_config *conf = hist->priv; in hist_reset_mem()
36 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR); in hist_reset_mem()
42 isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR); in hist_reset_mem()
48 for (i = OMAP3ISP_HIST_MEM_SIZE / 4; i > 0; i--) { in hist_reset_mem()
49 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); in hist_reset_mem()
50 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); in hist_reset_mem()
51 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); in hist_reset_mem()
52 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); in hist_reset_mem()
54 isp_reg_clr(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR); in hist_reset_mem()
56 hist->wait_acc_frames = conf->num_acc_frames; in hist_reset_mem()
60 * hist_setup_regs - Helper function to update Histogram registers.
64 struct isp_device *isp = hist->isp; in hist_setup_regs() local
72 if (!hist->update || hist->state == ISPSTAT_DISABLED || in hist_setup_regs()
73 hist->state == ISPSTAT_DISABLING) in hist_setup_regs()
76 cnt = conf->cfa << ISPHIST_CNT_CFA_SHIFT; in hist_setup_regs()
78 wb_gain = conf->wg[0] << ISPHIST_WB_GAIN_WG00_SHIFT; in hist_setup_regs()
79 wb_gain |= conf->wg[1] << ISPHIST_WB_GAIN_WG01_SHIFT; in hist_setup_regs()
80 wb_gain |= conf->wg[2] << ISPHIST_WB_GAIN_WG02_SHIFT; in hist_setup_regs()
81 if (conf->cfa == OMAP3ISP_HIST_CFA_BAYER) in hist_setup_regs()
82 wb_gain |= conf->wg[3] << ISPHIST_WB_GAIN_WG03_SHIFT; in hist_setup_regs()
85 for (c = 0; c < OMAP3ISP_HIST_MAX_REGIONS; c++) { in hist_setup_regs()
86 if (c < conf->num_regions) { in hist_setup_regs()
87 reg_hor[c] = (conf->region[c].h_start << in hist_setup_regs()
89 | (conf->region[c].h_end << in hist_setup_regs()
91 reg_ver[c] = (conf->region[c].v_start << in hist_setup_regs()
93 | (conf->region[c].v_end << in hist_setup_regs()
96 reg_hor[c] = 0; in hist_setup_regs()
97 reg_ver[c] = 0; in hist_setup_regs()
101 cnt |= conf->hist_bins << ISPHIST_CNT_BINS_SHIFT; in hist_setup_regs()
102 switch (conf->hist_bins) { in hist_setup_regs()
104 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 8) << in hist_setup_regs()
108 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 7) << in hist_setup_regs()
112 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 6) << in hist_setup_regs()
116 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 5) << in hist_setup_regs()
123 isp_reg_writel(isp, cnt, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT); in hist_setup_regs()
124 isp_reg_writel(isp, wb_gain, OMAP3_ISP_IOMEM_HIST, ISPHIST_WB_GAIN); in hist_setup_regs()
125 isp_reg_writel(isp, reg_hor[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_HORZ); in hist_setup_regs()
126 isp_reg_writel(isp, reg_ver[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_VERT); in hist_setup_regs()
127 isp_reg_writel(isp, reg_hor[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_HORZ); in hist_setup_regs()
128 isp_reg_writel(isp, reg_ver[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_VERT); in hist_setup_regs()
129 isp_reg_writel(isp, reg_hor[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_HORZ); in hist_setup_regs()
130 isp_reg_writel(isp, reg_ver[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_VERT); in hist_setup_regs()
131 isp_reg_writel(isp, reg_hor[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_HORZ); in hist_setup_regs()
132 isp_reg_writel(isp, reg_ver[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_VERT); in hist_setup_regs()
134 hist->update = 0; in hist_setup_regs()
135 hist->config_counter += hist->inc_config; in hist_setup_regs()
136 hist->inc_config = 0; in hist_setup_regs()
137 hist->buf_size = conf->buf_size; in hist_setup_regs()
143 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR, in hist_enable()
145 omap3isp_subclk_enable(hist->isp, OMAP3_ISP_SUBCLK_HIST); in hist_enable()
147 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR, in hist_enable()
149 omap3isp_subclk_disable(hist->isp, OMAP3_ISP_SUBCLK_HIST); in hist_enable()
155 return isp_reg_readl(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR) in hist_busy()
163 /* FIXME: The DMA engine API can't report transfer errors :-/ */ in hist_dma_cb()
165 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, in hist_dma_cb()
169 if (hist->state != ISPSTAT_DISABLED) in hist_dma_cb()
170 omap3isp_hist_dma_done(hist->isp); in hist_dma_cb()
175 dma_addr_t dma_addr = hist->active_buf->dma_addr; in hist_buf_dma()
182 dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n"); in hist_buf_dma()
186 isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR); in hist_buf_dma()
187 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, in hist_buf_dma()
189 omap3isp_flush(hist->isp); in hist_buf_dma()
191 memset(&cfg, 0, sizeof(cfg)); in hist_buf_dma()
192 cfg.src_addr = hist->isp->mmio_hist_base_phys + ISPHIST_DATA; in hist_buf_dma()
194 cfg.src_maxburst = hist->buf_size / 4; in hist_buf_dma()
196 ret = dmaengine_slave_config(hist->dma_ch, &cfg); in hist_buf_dma()
197 if (ret < 0) { in hist_buf_dma()
198 dev_dbg(hist->isp->dev, in hist_buf_dma()
203 tx = dmaengine_prep_slave_single(hist->dma_ch, dma_addr, in hist_buf_dma()
204 hist->buf_size, DMA_DEV_TO_MEM, in hist_buf_dma()
207 dev_dbg(hist->isp->dev, in hist_buf_dma()
212 tx->callback = hist_dma_cb; in hist_buf_dma()
213 tx->callback_param = hist; in hist_buf_dma()
214 cookie = tx->tx_submit(tx); in hist_buf_dma()
216 dev_dbg(hist->isp->dev, "hist: DMA submission failed\n"); in hist_buf_dma()
220 dma_async_issue_pending(hist->dma_ch); in hist_buf_dma()
231 struct isp_device *isp = hist->isp; in hist_buf_pio() local
232 u32 *buf = hist->active_buf->virt_addr; in hist_buf_pio()
236 dev_dbg(isp->dev, "hist: invalid PIO buffer address\n"); in hist_buf_pio()
241 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR); in hist_buf_pio()
248 isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR); in hist_buf_pio()
251 * We'll read 4 times a 4-bytes-word at each iteration for in hist_buf_pio()
255 for (i = hist->buf_size / 16; i > 0; i--) { in hist_buf_pio()
256 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); in hist_buf_pio()
257 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); in hist_buf_pio()
258 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); in hist_buf_pio()
259 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA); in hist_buf_pio()
261 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, in hist_buf_pio()
268 * hist_buf_process - Callback from ISP driver for HIST interrupt.
272 struct omap3isp_hist_config *user_cfg = hist->priv; in hist_buf_process()
275 if (atomic_read(&hist->buf_err) || hist->state != ISPSTAT_ENABLED) { in hist_buf_process()
280 if (--(hist->wait_acc_frames)) in hist_buf_process()
283 if (hist->dma_ch) in hist_buf_process()
288 hist->wait_acc_frames = user_cfg->num_acc_frames; in hist_buf_process()
295 return OMAP3ISP_HIST_MEM_SIZE_BINS(conf->hist_bins) * conf->num_regions; in hist_get_buf_size()
299 * hist_validate_params - Helper function to check user given params.
302 * Returns 0 on success configuration.
310 if (user_cfg->cfa > OMAP3ISP_HIST_CFA_FOVEONX3) in hist_validate_params()
311 return -EINVAL; in hist_validate_params()
315 if ((user_cfg->num_regions < OMAP3ISP_HIST_MIN_REGIONS) || in hist_validate_params()
316 (user_cfg->num_regions > OMAP3ISP_HIST_MAX_REGIONS)) in hist_validate_params()
317 return -EINVAL; in hist_validate_params()
320 for (c = 0; c < user_cfg->num_regions; c++) { in hist_validate_params()
321 if (user_cfg->region[c].h_start & ~ISPHIST_REG_START_END_MASK) in hist_validate_params()
322 return -EINVAL; in hist_validate_params()
323 if (user_cfg->region[c].h_end & ~ISPHIST_REG_START_END_MASK) in hist_validate_params()
324 return -EINVAL; in hist_validate_params()
325 if (user_cfg->region[c].v_start & ~ISPHIST_REG_START_END_MASK) in hist_validate_params()
326 return -EINVAL; in hist_validate_params()
327 if (user_cfg->region[c].v_end & ~ISPHIST_REG_START_END_MASK) in hist_validate_params()
328 return -EINVAL; in hist_validate_params()
329 if (user_cfg->region[c].h_start > user_cfg->region[c].h_end) in hist_validate_params()
330 return -EINVAL; in hist_validate_params()
331 if (user_cfg->region[c].v_start > user_cfg->region[c].v_end) in hist_validate_params()
332 return -EINVAL; in hist_validate_params()
335 switch (user_cfg->num_regions) { in hist_validate_params()
337 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_256) in hist_validate_params()
338 return -EINVAL; in hist_validate_params()
341 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_128) in hist_validate_params()
342 return -EINVAL; in hist_validate_params()
345 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_64) in hist_validate_params()
346 return -EINVAL; in hist_validate_params()
351 if (buf_size > user_cfg->buf_size) in hist_validate_params()
353 user_cfg->buf_size = buf_size; in hist_validate_params()
354 else if (user_cfg->buf_size > OMAP3ISP_HIST_MAX_BUF_SIZE) in hist_validate_params()
355 user_cfg->buf_size = OMAP3ISP_HIST_MAX_BUF_SIZE; in hist_validate_params()
357 return 0; in hist_validate_params()
363 struct omap3isp_hist_config *cur_cfg = hist->priv; in hist_comp_params()
366 if (cur_cfg->cfa != user_cfg->cfa) in hist_comp_params()
369 if (cur_cfg->num_acc_frames != user_cfg->num_acc_frames) in hist_comp_params()
372 if (cur_cfg->hist_bins != user_cfg->hist_bins) in hist_comp_params()
375 for (c = 0; c < OMAP3ISP_HIST_MAX_WG; c++) { in hist_comp_params()
376 if (c == 3 && user_cfg->cfa == OMAP3ISP_HIST_CFA_FOVEONX3) in hist_comp_params()
378 else if (cur_cfg->wg[c] != user_cfg->wg[c]) in hist_comp_params()
382 if (cur_cfg->num_regions != user_cfg->num_regions) in hist_comp_params()
386 for (c = 0; c < user_cfg->num_regions; c++) { in hist_comp_params()
387 if (cur_cfg->region[c].h_start != user_cfg->region[c].h_start) in hist_comp_params()
389 if (cur_cfg->region[c].h_end != user_cfg->region[c].h_end) in hist_comp_params()
391 if (cur_cfg->region[c].v_start != user_cfg->region[c].v_start) in hist_comp_params()
393 if (cur_cfg->region[c].v_end != user_cfg->region[c].v_end) in hist_comp_params()
397 return 0; in hist_comp_params()
401 * hist_update_params - Helper function to check and store user given params.
407 struct omap3isp_hist_config *cur_cfg = hist->priv; in hist_set_params()
409 if (!hist->configured || hist_comp_params(hist, user_cfg)) { in hist_set_params()
411 if (user_cfg->num_acc_frames == 0) in hist_set_params()
412 user_cfg->num_acc_frames = 1; in hist_set_params()
413 hist->inc_config++; in hist_set_params()
414 hist->update = 1; in hist_set_params()
419 * instead of stick with user_cfg->buf_size. in hist_set_params()
421 cur_cfg->buf_size = hist_get_buf_size(cur_cfg); in hist_set_params()
443 return -ENOIOCTLCMD; in hist_ioctl()
472 * omap3isp_hist_init - Module Initialization.
474 int omap3isp_hist_init(struct isp_device *isp) in omap3isp_hist_init() argument
476 struct ispstat *hist = &isp->isp_hist; in omap3isp_hist_init()
482 return -ENOMEM; in omap3isp_hist_init()
484 hist->isp = isp; in omap3isp_hist_init()
498 hist->dma_ch = dma_request_chan_by_mask(&mask); in omap3isp_hist_init()
499 if (IS_ERR(hist->dma_ch)) { in omap3isp_hist_init()
500 ret = PTR_ERR(hist->dma_ch); in omap3isp_hist_init()
501 if (ret == -EPROBE_DEFER) in omap3isp_hist_init()
504 hist->dma_ch = NULL; in omap3isp_hist_init()
505 dev_warn(isp->dev, in omap3isp_hist_init()
508 dev_dbg(isp->dev, "hist: using DMA channel %s\n", in omap3isp_hist_init()
509 dma_chan_name(hist->dma_ch)); in omap3isp_hist_init()
513 hist->ops = &hist_ops; in omap3isp_hist_init()
514 hist->priv = hist_cfg; in omap3isp_hist_init()
515 hist->event_type = V4L2_EVENT_OMAP3ISP_HIST; in omap3isp_hist_init()
521 if (!IS_ERR_OR_NULL(hist->dma_ch)) in omap3isp_hist_init()
522 dma_release_channel(hist->dma_ch); in omap3isp_hist_init()
530 * omap3isp_hist_cleanup - Module cleanup.
532 void omap3isp_hist_cleanup(struct isp_device *isp) in omap3isp_hist_cleanup() argument
534 struct ispstat *hist = &isp->isp_hist; in omap3isp_hist_cleanup()
536 if (hist->dma_ch) in omap3isp_hist_cleanup()
537 dma_release_channel(hist->dma_ch); in omap3isp_hist_cleanup()