Lines Matching +full:isp +full:- +full:0
1 // SPDX-License-Identifier: GPL-2.0-only
5 * TI OMAP3 ISP - CSI2 module
14 #include <media/v4l2-common.h>
15 #include <linux/v4l2-mediabus.h>
18 #include "isp.h"
23 * csi2_if_enable - Enable CSI2 Receiver interface.
27 static void csi2_if_enable(struct isp_device *isp, in csi2_if_enable() argument
30 struct isp_csi2_ctrl_cfg *currctrl = &csi2->ctrl; in csi2_if_enable()
32 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_CTRL, ISPCSI2_CTRL_IF_EN, in csi2_if_enable()
33 enable ? ISPCSI2_CTRL_IF_EN : 0); in csi2_if_enable()
35 currctrl->if_enable = enable; in csi2_if_enable()
39 * csi2_recv_config - CSI2 receiver module configuration.
43 static void csi2_recv_config(struct isp_device *isp, in csi2_recv_config() argument
49 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTRL); in csi2_recv_config()
51 if (currctrl->frame_mode) in csi2_recv_config()
56 if (currctrl->vp_clk_enable) in csi2_recv_config()
61 if (currctrl->vp_only_enable) in csi2_recv_config()
67 reg |= currctrl->vp_out_ctrl << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT; in csi2_recv_config()
69 if (currctrl->ecc_enable) in csi2_recv_config()
74 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTRL); in csi2_recv_config()
91 * - 3 different formats (at this time)
92 * - 2 destinations (mem, vp+mem) (vp only handled separately)
93 * - 2 decompression options (on, off)
94 * - 2 isp revisions (certain format must be handled differently on OMAP3630)
97 * Not all combinations are valid. 0 means invalid.
107 { 0, 0 },
115 { 0, 0 },
146 { 0, 0 },
154 { 0, 0 },
160 * csi2_ctx_map_format - Map CSI2 sink media bus format to CSI2 format ID
161 * @csi2: ISP CSI2 device
167 const struct v4l2_mbus_framefmt *fmt = &csi2->formats[CSI2_PAD_SINK]; in csi2_ctx_map_format()
170 switch (fmt->code) { in csi2_ctx_map_format()
175 fmtidx = 0; in csi2_ctx_map_format()
188 fmt->code); in csi2_ctx_map_format()
189 return 0; in csi2_ctx_map_format()
192 if (!(csi2->output & CSI2_OUTPUT_CCDC) && in csi2_ctx_map_format()
193 !(csi2->output & CSI2_OUTPUT_MEMORY)) { in csi2_ctx_map_format()
201 destidx = csi2->frame_skip ? 0 : !!(csi2->output & CSI2_OUTPUT_CCDC); in csi2_ctx_map_format()
202 is_3630 = csi2->isp->revision == ISP_REVISION_15_0; in csi2_ctx_map_format()
204 return __csi2_fmt_map[fmtidx][destidx][csi2->dpcm_decompress][is_3630]; in csi2_ctx_map_format()
208 * csi2_set_outaddr - Set memory address to save output image
209 * @csi2: Pointer to ISP CSI2a device.
210 * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
214 * Returns 0 if successful, or -EINVAL if the address is not in the 32 byte
219 struct isp_device *isp = csi2->isp; in csi2_set_outaddr() local
220 struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[0]; in csi2_set_outaddr()
222 ctx->ping_addr = addr; in csi2_set_outaddr()
223 ctx->pong_addr = addr; in csi2_set_outaddr()
224 isp_reg_writel(isp, ctx->ping_addr, in csi2_set_outaddr()
225 csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum)); in csi2_set_outaddr()
226 isp_reg_writel(isp, ctx->pong_addr, in csi2_set_outaddr()
227 csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum)); in csi2_set_outaddr()
231 * is_usr_def_mapping - Checks whether USER_DEF_MAPPING should
238 return (format_id & 0x40) ? 1 : 0; in is_usr_def_mapping()
242 * csi2_ctx_enable - Enable specified CSI2 context
243 * @ctxnum: Context number, valid between 0 and 7 values.
247 static void csi2_ctx_enable(struct isp_device *isp, in csi2_ctx_enable() argument
250 struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[ctxnum]; in csi2_ctx_enable()
251 unsigned int skip = 0; in csi2_ctx_enable()
254 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum)); in csi2_ctx_enable()
257 if (csi2->frame_skip) in csi2_ctx_enable()
258 skip = csi2->frame_skip; in csi2_ctx_enable()
259 else if (csi2->output & CSI2_OUTPUT_MEMORY) in csi2_ctx_enable()
270 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum)); in csi2_ctx_enable()
271 ctx->enabled = enable; in csi2_ctx_enable()
275 * csi2_ctx_config - CSI2 context configuration.
279 static void csi2_ctx_config(struct isp_device *isp, in csi2_ctx_config() argument
286 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum)); in csi2_ctx_config()
288 if (ctx->eof_enabled) in csi2_ctx_config()
293 if (ctx->eol_enabled) in csi2_ctx_config()
298 if (ctx->checksum_enabled) in csi2_ctx_config()
303 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum)); in csi2_ctx_config()
306 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum)); in csi2_ctx_config()
309 reg |= ctx->virtual_id << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT; in csi2_ctx_config()
312 reg |= ctx->format_id << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT; in csi2_ctx_config()
314 if (ctx->dpcm_decompress) { in csi2_ctx_config()
315 if (ctx->dpcm_predictor) in csi2_ctx_config()
321 if (is_usr_def_mapping(ctx->format_id)) { in csi2_ctx_config()
326 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum)); in csi2_ctx_config()
329 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum)); in csi2_ctx_config()
331 reg |= (ctx->alpha << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT); in csi2_ctx_config()
333 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum)); in csi2_ctx_config()
336 reg = isp_reg_readl(isp, csi2->regs1, in csi2_ctx_config()
337 ISPCSI2_CTX_DAT_OFST(ctx->ctxnum)); in csi2_ctx_config()
339 reg |= ctx->data_offset << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT; in csi2_ctx_config()
340 isp_reg_writel(isp, reg, csi2->regs1, in csi2_ctx_config()
341 ISPCSI2_CTX_DAT_OFST(ctx->ctxnum)); in csi2_ctx_config()
343 isp_reg_writel(isp, ctx->ping_addr, in csi2_ctx_config()
344 csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum)); in csi2_ctx_config()
346 isp_reg_writel(isp, ctx->pong_addr, in csi2_ctx_config()
347 csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum)); in csi2_ctx_config()
351 * csi2_timing_config - CSI2 timing configuration.
354 static void csi2_timing_config(struct isp_device *isp, in csi2_timing_config() argument
360 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_TIMING); in csi2_timing_config()
362 if (timing->force_rx_mode) in csi2_timing_config()
363 reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum); in csi2_timing_config()
365 reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum); in csi2_timing_config()
367 if (timing->stop_state_16x) in csi2_timing_config()
368 reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum); in csi2_timing_config()
370 reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum); in csi2_timing_config()
372 if (timing->stop_state_4x) in csi2_timing_config()
373 reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum); in csi2_timing_config()
375 reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum); in csi2_timing_config()
377 reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(timing->ionum); in csi2_timing_config()
378 reg |= timing->stop_state_counter << in csi2_timing_config()
379 ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(timing->ionum); in csi2_timing_config()
381 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_TIMING); in csi2_timing_config()
385 * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
388 static void csi2_irq_ctx_set(struct isp_device *isp, in csi2_irq_ctx_set() argument
393 for (i = 0; i < 8; i++) { in csi2_irq_ctx_set()
394 isp_reg_writel(isp, ISPCSI2_CTX_IRQSTATUS_FE_IRQ, csi2->regs1, in csi2_irq_ctx_set()
397 isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i), in csi2_irq_ctx_set()
400 isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i), in csi2_irq_ctx_set()
406 * csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs.
409 static void csi2_irq_complexio1_set(struct isp_device *isp, in csi2_irq_complexio1_set() argument
440 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQSTATUS); in csi2_irq_complexio1_set()
442 reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_PHY_IRQENABLE); in csi2_irq_complexio1_set()
444 reg = 0; in csi2_irq_complexio1_set()
445 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQENABLE); in csi2_irq_complexio1_set()
449 * csi2_irq_status_set - Enables CSI2 Status IRQs.
452 static void csi2_irq_status_set(struct isp_device *isp, in csi2_irq_status_set() argument
463 ISPCSI2_IRQSTATUS_CONTEXT(0); in csi2_irq_status_set()
464 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQSTATUS); in csi2_irq_status_set()
466 reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQENABLE); in csi2_irq_status_set()
468 reg = 0; in csi2_irq_status_set()
470 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQENABLE); in csi2_irq_status_set()
474 * omap3isp_csi2_reset - Resets the CSI2 module.
478 * Returns 0 if successful, or -EBUSY if power command didn't respond.
482 struct isp_device *isp = csi2->isp; in omap3isp_csi2_reset() local
483 u8 soft_reset_retries = 0; in omap3isp_csi2_reset()
487 if (!csi2->available) in omap3isp_csi2_reset()
488 return -ENODEV; in omap3isp_csi2_reset()
490 if (csi2->phy->entity) in omap3isp_csi2_reset()
491 return -EBUSY; in omap3isp_csi2_reset()
493 isp_reg_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG, in omap3isp_csi2_reset()
497 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_SYSSTATUS) & in omap3isp_csi2_reset()
507 dev_err(isp->dev, "CSI2: Soft reset try count exceeded!\n"); in omap3isp_csi2_reset()
508 return -EBUSY; in omap3isp_csi2_reset()
511 if (isp->revision == ISP_REVISION_15_0) in omap3isp_csi2_reset()
512 isp_reg_set(isp, csi2->regs1, ISPCSI2_PHY_CFG, in omap3isp_csi2_reset()
517 reg = isp_reg_readl(isp, csi2->phy->phy_regs, ISPCSIPHY_REG1) in omap3isp_csi2_reset()
522 } while (--i > 0); in omap3isp_csi2_reset()
524 if (i == 0) { in omap3isp_csi2_reset()
525 dev_err(isp->dev, in omap3isp_csi2_reset()
527 return -EBUSY; in omap3isp_csi2_reset()
530 if (isp->autoidle) in omap3isp_csi2_reset()
531 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG, in omap3isp_csi2_reset()
535 ((isp->revision == ISP_REVISION_15_0) ? in omap3isp_csi2_reset()
536 ISPCSI2_SYSCONFIG_AUTO_IDLE : 0)); in omap3isp_csi2_reset()
538 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG, in omap3isp_csi2_reset()
543 return 0; in omap3isp_csi2_reset()
548 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); in csi2_configure()
550 struct isp_device *isp = csi2->isp; in csi2_configure() local
551 struct isp_csi2_timing_cfg *timing = &csi2->timing[0]; in csi2_configure()
561 if (csi2->contexts[0].enabled || csi2->ctrl.if_enable) in csi2_configure()
562 return -EBUSY; in csi2_configure()
564 pad = media_pad_remote_pad_first(&csi2->pads[CSI2_PAD_SINK]); in csi2_configure()
565 sensor = media_entity_to_v4l2_subdev(pad->entity); in csi2_configure()
566 buscfg = v4l2_subdev_to_bus_cfg(pipe->external); in csi2_configure()
568 return -EPIPE; in csi2_configure()
570 csi2->frame_skip = 0; in csi2_configure()
571 v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip); in csi2_configure()
573 csi2->ctrl.vp_out_ctrl = in csi2_configure()
574 clamp_t(unsigned int, pipe->l3_ick / pipe->external_rate - 1, in csi2_configure()
576 dev_dbg(isp->dev, "%s: l3_ick %lu, external_rate %u, vp_out_ctrl %u\n", in csi2_configure()
577 __func__, pipe->l3_ick, pipe->external_rate, in csi2_configure()
578 csi2->ctrl.vp_out_ctrl); in csi2_configure()
579 csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE; in csi2_configure()
580 csi2->ctrl.ecc_enable = buscfg->bus.csi2.crc; in csi2_configure()
582 timing->ionum = 1; in csi2_configure()
583 timing->force_rx_mode = 1; in csi2_configure()
584 timing->stop_state_16x = 1; in csi2_configure()
585 timing->stop_state_4x = 1; in csi2_configure()
586 timing->stop_state_counter = 0x1FF; in csi2_configure()
593 if (csi2->formats[CSI2_PAD_SINK].code != in csi2_configure()
594 csi2->formats[CSI2_PAD_SOURCE].code) in csi2_configure()
595 csi2->dpcm_decompress = true; in csi2_configure()
597 csi2->dpcm_decompress = false; in csi2_configure()
599 csi2->contexts[0].format_id = csi2_ctx_map_format(csi2); in csi2_configure()
601 if (csi2->video_out.bpl_padding == 0) in csi2_configure()
602 csi2->contexts[0].data_offset = 0; in csi2_configure()
604 csi2->contexts[0].data_offset = csi2->video_out.bpl_value; in csi2_configure()
608 * context 0. These signals are generated from CSI2 receiver to in csi2_configure()
613 csi2->contexts[0].eof_enabled = 1; in csi2_configure()
614 csi2->contexts[0].eol_enabled = 1; in csi2_configure()
616 csi2_irq_complexio1_set(isp, csi2, 1); in csi2_configure()
617 csi2_irq_ctx_set(isp, csi2, 1); in csi2_configure()
618 csi2_irq_status_set(isp, csi2, 1); in csi2_configure()
621 csi2_timing_config(isp, csi2, timing); in csi2_configure()
622 csi2_recv_config(isp, csi2, &csi2->ctrl); in csi2_configure()
623 csi2_ctx_config(isp, csi2, &csi2->contexts[0]); in csi2_configure()
625 return 0; in csi2_configure()
629 * csi2_print_status - Prints CSI2 debug information.
631 #define CSI2_PRINT_REGISTER(isp, regs, name)\ argument
632 dev_dbg(isp->dev, "###CSI2 " #name "=0x%08x\n", \
633 isp_reg_readl(isp, regs, ISPCSI2_##name))
637 struct isp_device *isp = csi2->isp; in csi2_print_status() local
639 if (!csi2->available) in csi2_print_status()
642 dev_dbg(isp->dev, "-------------CSI2 Register dump-------------\n"); in csi2_print_status()
644 CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSCONFIG); in csi2_print_status()
645 CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSSTATUS); in csi2_print_status()
646 CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQENABLE); in csi2_print_status()
647 CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQSTATUS); in csi2_print_status()
648 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTRL); in csi2_print_status()
649 CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_H); in csi2_print_status()
650 CSI2_PRINT_REGISTER(isp, csi2->regs1, GNQ); in csi2_print_status()
651 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_CFG); in csi2_print_status()
652 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQSTATUS); in csi2_print_status()
653 CSI2_PRINT_REGISTER(isp, csi2->regs1, SHORT_PACKET); in csi2_print_status()
654 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQENABLE); in csi2_print_status()
655 CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_P); in csi2_print_status()
656 CSI2_PRINT_REGISTER(isp, csi2->regs1, TIMING); in csi2_print_status()
657 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL1(0)); in csi2_print_status()
658 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL2(0)); in csi2_print_status()
659 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_OFST(0)); in csi2_print_status()
660 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PING_ADDR(0)); in csi2_print_status()
661 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PONG_ADDR(0)); in csi2_print_status()
662 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQENABLE(0)); in csi2_print_status()
663 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQSTATUS(0)); in csi2_print_status()
664 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL3(0)); in csi2_print_status()
666 dev_dbg(isp->dev, "--------------------------------------------\n"); in csi2_print_status()
669 /* -----------------------------------------------------------------------------
674 * csi2_isr_buffer - Does buffer handling at end-of-frame
679 struct isp_device *isp = csi2->isp; in csi2_isr_buffer() local
682 csi2_ctx_enable(isp, csi2, 0, 0); in csi2_isr_buffer()
684 buffer = omap3isp_video_buffer_next(&csi2->video_out); in csi2_isr_buffer()
693 csi2_set_outaddr(csi2, buffer->dma); in csi2_isr_buffer()
694 csi2_ctx_enable(isp, csi2, 0, 1); in csi2_isr_buffer()
700 struct isp_device *isp = csi2->isp; in csi2_isr_ctx() local
701 unsigned int n = ctx->ctxnum; in csi2_isr_ctx()
704 status = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n)); in csi2_isr_ctx()
705 isp_reg_writel(isp, status, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n)); in csi2_isr_ctx()
712 * in the CSI2_CTx_CTRL1::COUNT field, so re-enable it. in csi2_isr_ctx()
717 * correctly and reaches 0 when data is forwarded to the video port only in csi2_isr_ctx()
720 if (csi2->frame_skip) { in csi2_isr_ctx()
721 csi2->frame_skip--; in csi2_isr_ctx()
722 if (csi2->frame_skip == 0) { in csi2_isr_ctx()
723 ctx->format_id = csi2_ctx_map_format(csi2); in csi2_isr_ctx()
724 csi2_ctx_config(isp, csi2, ctx); in csi2_isr_ctx()
725 csi2_ctx_enable(isp, csi2, n, 1); in csi2_isr_ctx()
730 if (csi2->output & CSI2_OUTPUT_MEMORY) in csi2_isr_ctx()
735 * omap3isp_csi2_isr - CSI2 interrupt handling.
739 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); in omap3isp_csi2_isr()
741 struct isp_device *isp = csi2->isp; in omap3isp_csi2_isr() local
743 if (!csi2->available) in omap3isp_csi2_isr()
746 csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS); in omap3isp_csi2_isr()
747 isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS); in omap3isp_csi2_isr()
751 cpxio1_irqstatus = isp_reg_readl(isp, csi2->regs1, in omap3isp_csi2_isr()
753 isp_reg_writel(isp, cpxio1_irqstatus, in omap3isp_csi2_isr()
754 csi2->regs1, ISPCSI2_PHY_IRQSTATUS); in omap3isp_csi2_isr()
755 dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ %x\n", in omap3isp_csi2_isr()
757 pipe->error = true; in omap3isp_csi2_isr()
765 dev_dbg(isp->dev, in omap3isp_csi2_isr()
768 ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) ? 1 : 0, in omap3isp_csi2_isr()
770 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ) ? 1 : 0, in omap3isp_csi2_isr()
772 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ) ? 1 : 0, in omap3isp_csi2_isr()
774 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0, in omap3isp_csi2_isr()
776 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0); in omap3isp_csi2_isr()
777 pipe->error = true; in omap3isp_csi2_isr()
780 if (omap3isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping)) in omap3isp_csi2_isr()
784 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0)) in omap3isp_csi2_isr()
785 csi2_isr_ctx(csi2, &csi2->contexts[0]); in omap3isp_csi2_isr()
788 dev_dbg(isp->dev, "CSI2: ECC correction done\n"); in omap3isp_csi2_isr()
791 /* -----------------------------------------------------------------------------
792 * ISP video operations
796 * csi2_queue - Queues the first buffer when using memory output
802 struct isp_device *isp = video->isp; in csi2_queue() local
803 struct isp_csi2_device *csi2 = &isp->isp_csi2a; in csi2_queue()
805 csi2_set_outaddr(csi2, buffer->dma); in csi2_queue()
813 if (csi2->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) { in csi2_queue()
814 /* Enable / disable context 0 and IRQs */ in csi2_queue()
815 csi2_if_enable(isp, csi2, 1); in csi2_queue()
816 csi2_ctx_enable(isp, csi2, 0, 1); in csi2_queue()
817 isp_video_dmaqueue_flags_clr(&csi2->video_out); in csi2_queue()
820 return 0; in csi2_queue()
827 /* -----------------------------------------------------------------------------
839 return &csi2->formats[pad]; in __csi2_get_format()
855 /* Clamp the width and height to valid range (1-8191). */ in csi2_try_format()
856 for (i = 0; i < ARRAY_SIZE(csi2_input_fmts); i++) { in csi2_try_format()
857 if (fmt->code == csi2_input_fmts[i]) in csi2_try_format()
863 fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; in csi2_try_format()
865 fmt->width = clamp_t(u32, fmt->width, 1, 8191); in csi2_try_format()
866 fmt->height = clamp_t(u32, fmt->height, 1, 8191); in csi2_try_format()
873 pixelcode = fmt->code; in csi2_try_format()
882 info = omap3isp_video_format_info(fmt->code); in csi2_try_format()
883 if (info->uncompressed == pixelcode) in csi2_try_format()
884 fmt->code = pixelcode; in csi2_try_format()
888 /* RGB, non-interlaced */ in csi2_try_format()
889 fmt->colorspace = V4L2_COLORSPACE_SRGB; in csi2_try_format()
890 fmt->field = V4L2_FIELD_NONE; in csi2_try_format()
894 * csi2_enum_mbus_code - Handle pixel format enumeration
898 * return -EINVAL or zero on success
908 if (code->pad == CSI2_PAD_SINK) { in csi2_enum_mbus_code()
909 if (code->index >= ARRAY_SIZE(csi2_input_fmts)) in csi2_enum_mbus_code()
910 return -EINVAL; in csi2_enum_mbus_code()
912 code->code = csi2_input_fmts[code->index]; in csi2_enum_mbus_code()
915 code->which); in csi2_enum_mbus_code()
916 switch (code->index) { in csi2_enum_mbus_code()
917 case 0: in csi2_enum_mbus_code()
919 code->code = format->code; in csi2_enum_mbus_code()
923 info = omap3isp_video_format_info(format->code); in csi2_enum_mbus_code()
924 if (info->uncompressed == format->code) in csi2_enum_mbus_code()
925 return -EINVAL; in csi2_enum_mbus_code()
927 code->code = info->uncompressed; in csi2_enum_mbus_code()
930 return -EINVAL; in csi2_enum_mbus_code()
934 return 0; in csi2_enum_mbus_code()
944 if (fse->index != 0) in csi2_enum_frame_size()
945 return -EINVAL; in csi2_enum_frame_size()
947 format.code = fse->code; in csi2_enum_frame_size()
950 csi2_try_format(csi2, sd_state, fse->pad, &format, fse->which); in csi2_enum_frame_size()
951 fse->min_width = format.width; in csi2_enum_frame_size()
952 fse->min_height = format.height; in csi2_enum_frame_size()
954 if (format.code != fse->code) in csi2_enum_frame_size()
955 return -EINVAL; in csi2_enum_frame_size()
957 format.code = fse->code; in csi2_enum_frame_size()
958 format.width = -1; in csi2_enum_frame_size()
959 format.height = -1; in csi2_enum_frame_size()
960 csi2_try_format(csi2, sd_state, fse->pad, &format, fse->which); in csi2_enum_frame_size()
961 fse->max_width = format.width; in csi2_enum_frame_size()
962 fse->max_height = format.height; in csi2_enum_frame_size()
964 return 0; in csi2_enum_frame_size()
968 * csi2_get_format - Handle get format by pads subdev method
972 * return -EINVAL or zero on success
981 format = __csi2_get_format(csi2, sd_state, fmt->pad, fmt->which); in csi2_get_format()
983 return -EINVAL; in csi2_get_format()
985 fmt->format = *format; in csi2_get_format()
986 return 0; in csi2_get_format()
990 * csi2_set_format - Handle set format by pads subdev method
994 * return -EINVAL or zero on success
1003 format = __csi2_get_format(csi2, sd_state, fmt->pad, fmt->which); in csi2_set_format()
1005 return -EINVAL; in csi2_set_format()
1007 csi2_try_format(csi2, sd_state, fmt->pad, &fmt->format, fmt->which); in csi2_set_format()
1008 *format = fmt->format; in csi2_set_format()
1011 if (fmt->pad == CSI2_PAD_SINK) { in csi2_set_format()
1013 fmt->which); in csi2_set_format()
1014 *format = fmt->format; in csi2_set_format()
1016 fmt->which); in csi2_set_format()
1019 return 0; in csi2_set_format()
1023 * csi2_init_formats - Initialize formats on all pads
1024 * @sd: ISP CSI2 V4L2 subdevice
1035 memset(&format, 0, sizeof(format)); in csi2_init_formats()
1041 csi2_set_format(sd, fh ? fh->state : NULL, &format); in csi2_init_formats()
1043 return 0; in csi2_init_formats()
1047 * csi2_set_stream - Enable/Disable streaming on the CSI2 module
1048 * @sd: ISP CSI2 V4L2 subdevice
1049 * @enable: ISP pipeline stream state
1051 * Return 0 on success or a negative error code otherwise.
1056 struct isp_device *isp = csi2->isp; in csi2_set_stream() local
1057 struct isp_video *video_out = &csi2->video_out; in csi2_set_stream()
1061 if (omap3isp_csiphy_acquire(csi2->phy, &sd->entity) < 0) in csi2_set_stream()
1062 return -ENODEV; in csi2_set_stream()
1063 if (csi2->output & CSI2_OUTPUT_MEMORY) in csi2_set_stream()
1064 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI2A_WRITE); in csi2_set_stream()
1074 if (csi2->output & CSI2_OUTPUT_MEMORY && in csi2_set_stream()
1075 !(video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED)) in csi2_set_stream()
1077 /* Enable context 0 and IRQs */ in csi2_set_stream()
1078 atomic_set(&csi2->stopping, 0); in csi2_set_stream()
1079 csi2_ctx_enable(isp, csi2, 0, 1); in csi2_set_stream()
1080 csi2_if_enable(isp, csi2, 1); in csi2_set_stream()
1085 if (csi2->state == ISP_PIPELINE_STREAM_STOPPED) in csi2_set_stream()
1086 return 0; in csi2_set_stream()
1087 if (omap3isp_module_sync_idle(&sd->entity, &csi2->wait, in csi2_set_stream()
1088 &csi2->stopping)) in csi2_set_stream()
1089 dev_dbg(isp->dev, "%s: module stop timeout.\n", in csi2_set_stream()
1090 sd->name); in csi2_set_stream()
1091 csi2_ctx_enable(isp, csi2, 0, 0); in csi2_set_stream()
1092 csi2_if_enable(isp, csi2, 0); in csi2_set_stream()
1093 csi2_irq_ctx_set(isp, csi2, 0); in csi2_set_stream()
1094 omap3isp_csiphy_release(csi2->phy); in csi2_set_stream()
1096 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI2A_WRITE); in csi2_set_stream()
1100 csi2->state = enable; in csi2_set_stream()
1101 return 0; in csi2_set_stream()
1128 /* -----------------------------------------------------------------------------
1133 * csi2_link_setup - Setup CSI2 connections.
1138 * return -EINVAL or zero on success
1146 struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl; in csi2_link_setup()
1147 unsigned int index = local->index; in csi2_link_setup()
1150 * The ISP core doesn't support pipelines with multiple video outputs. in csi2_link_setup()
1151 * Revisit this when it will be implemented, and return -EBUSY for now. in csi2_link_setup()
1155 if (is_media_entity_v4l2_subdev(remote->entity)) in csi2_link_setup()
1161 if (csi2->output & ~CSI2_OUTPUT_MEMORY) in csi2_link_setup()
1162 return -EBUSY; in csi2_link_setup()
1163 csi2->output |= CSI2_OUTPUT_MEMORY; in csi2_link_setup()
1165 csi2->output &= ~CSI2_OUTPUT_MEMORY; in csi2_link_setup()
1171 if (csi2->output & ~CSI2_OUTPUT_CCDC) in csi2_link_setup()
1172 return -EBUSY; in csi2_link_setup()
1173 csi2->output |= CSI2_OUTPUT_CCDC; in csi2_link_setup()
1175 csi2->output &= ~CSI2_OUTPUT_CCDC; in csi2_link_setup()
1181 return -EINVAL; in csi2_link_setup()
1184 ctrl->vp_only_enable = in csi2_link_setup()
1185 (csi2->output & CSI2_OUTPUT_MEMORY) ? false : true; in csi2_link_setup()
1186 ctrl->vp_clk_enable = !!(csi2->output & CSI2_OUTPUT_CCDC); in csi2_link_setup()
1188 return 0; in csi2_link_setup()
1199 v4l2_device_unregister_subdev(&csi2->subdev); in omap3isp_csi2_unregister_entities()
1200 omap3isp_video_unregister(&csi2->video_out); in omap3isp_csi2_unregister_entities()
1209 csi2->subdev.dev = vdev->mdev->dev; in omap3isp_csi2_register_entities()
1210 ret = v4l2_device_register_subdev(vdev, &csi2->subdev); in omap3isp_csi2_register_entities()
1211 if (ret < 0) in omap3isp_csi2_register_entities()
1214 ret = omap3isp_video_register(&csi2->video_out, vdev); in omap3isp_csi2_register_entities()
1215 if (ret < 0) in omap3isp_csi2_register_entities()
1218 return 0; in omap3isp_csi2_register_entities()
1225 /* -----------------------------------------------------------------------------
1226 * ISP CSI2 initialisation and cleanup
1230 * csi2_init_entities - Initialize subdev and media entity.
1232 * return -ENOMEM or zero on success
1236 struct v4l2_subdev *sd = &csi2->subdev; in csi2_init_entities()
1237 struct media_pad *pads = csi2->pads; in csi2_init_entities()
1238 struct media_entity *me = &sd->entity; in csi2_init_entities()
1242 sd->internal_ops = &csi2_internal_ops; in csi2_init_entities()
1243 strscpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name)); in csi2_init_entities()
1245 sd->grp_id = 1 << 16; /* group ID for isp subdevs */ in csi2_init_entities()
1247 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in csi2_init_entities()
1253 me->ops = &csi2_media_ops; in csi2_init_entities()
1255 if (ret < 0) in csi2_init_entities()
1261 csi2->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in csi2_init_entities()
1262 csi2->video_out.ops = &csi2_ispvideo_ops; in csi2_init_entities()
1263 csi2->video_out.bpl_alignment = 32; in csi2_init_entities()
1264 csi2->video_out.bpl_zero_padding = 1; in csi2_init_entities()
1265 csi2->video_out.bpl_max = 0x1ffe0; in csi2_init_entities()
1266 csi2->video_out.isp = csi2->isp; in csi2_init_entities()
1267 csi2->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3; in csi2_init_entities()
1269 ret = omap3isp_video_init(&csi2->video_out, "CSI2a"); in csi2_init_entities()
1270 if (ret < 0) in csi2_init_entities()
1273 return 0; in csi2_init_entities()
1276 media_entity_cleanup(&csi2->subdev.entity); in csi2_init_entities()
1281 * omap3isp_csi2_init - Routine for module driver init
1283 int omap3isp_csi2_init(struct isp_device *isp) in omap3isp_csi2_init() argument
1285 struct isp_csi2_device *csi2a = &isp->isp_csi2a; in omap3isp_csi2_init()
1286 struct isp_csi2_device *csi2c = &isp->isp_csi2c; in omap3isp_csi2_init()
1289 csi2a->isp = isp; in omap3isp_csi2_init()
1290 csi2a->available = 1; in omap3isp_csi2_init()
1291 csi2a->regs1 = OMAP3_ISP_IOMEM_CSI2A_REGS1; in omap3isp_csi2_init()
1292 csi2a->regs2 = OMAP3_ISP_IOMEM_CSI2A_REGS2; in omap3isp_csi2_init()
1293 csi2a->phy = &isp->isp_csiphy2; in omap3isp_csi2_init()
1294 csi2a->state = ISP_PIPELINE_STREAM_STOPPED; in omap3isp_csi2_init()
1295 init_waitqueue_head(&csi2a->wait); in omap3isp_csi2_init()
1298 if (ret < 0) in omap3isp_csi2_init()
1301 if (isp->revision == ISP_REVISION_15_0) { in omap3isp_csi2_init()
1302 csi2c->isp = isp; in omap3isp_csi2_init()
1303 csi2c->available = 1; in omap3isp_csi2_init()
1304 csi2c->regs1 = OMAP3_ISP_IOMEM_CSI2C_REGS1; in omap3isp_csi2_init()
1305 csi2c->regs2 = OMAP3_ISP_IOMEM_CSI2C_REGS2; in omap3isp_csi2_init()
1306 csi2c->phy = &isp->isp_csiphy1; in omap3isp_csi2_init()
1307 csi2c->state = ISP_PIPELINE_STREAM_STOPPED; in omap3isp_csi2_init()
1308 init_waitqueue_head(&csi2c->wait); in omap3isp_csi2_init()
1311 return 0; in omap3isp_csi2_init()
1315 * omap3isp_csi2_cleanup - Routine for module driver cleanup
1317 void omap3isp_csi2_cleanup(struct isp_device *isp) in omap3isp_csi2_cleanup() argument
1319 struct isp_csi2_device *csi2a = &isp->isp_csi2a; in omap3isp_csi2_cleanup()
1321 omap3isp_video_cleanup(&csi2a->video_out); in omap3isp_csi2_cleanup()
1322 media_entity_cleanup(&csi2a->subdev.entity); in omap3isp_csi2_cleanup()