예제 #1
0
파일: iss_csi2.c 프로젝트: MaxChina/linux
static void csi2_isr_ctx(struct iss_csi2_device *csi2,
			 struct iss_csi2_ctx_cfg *ctx)
{
	unsigned int n = ctx->ctxnum;
	u32 status;

	status = iss_reg_read(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(n));
	iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(n), status);

	/* Propagate frame number */
	if (status & CSI2_CTX_IRQ_FS) {
		struct iss_pipeline *pipe =
				     to_iss_pipeline(&csi2->subdev.entity);
		if (pipe->do_propagation)
			atomic_inc(&pipe->frame_number);
	}

	if (!(status & CSI2_CTX_IRQ_FE))
		return;

	/* Skip interrupts until we reach the frame skip count. The CSI2 will be
	 * automatically disabled, as the frame skip count has been programmed
	 * in the CSI2_CTx_CTRL1::COUNT field, so reenable it.
	 *
	 * It would have been nice to rely on the FRAME_NUMBER interrupt instead
	 * but it turned out that the interrupt is only generated when the CSI2
	 * writes to memory (the CSI2_CTx_CTRL1::COUNT field is decreased
	 * correctly and reaches 0 when data is forwarded to the video port only
	 * but no interrupt arrives). Maybe a CSI2 hardware bug.
	 */
	if (csi2->frame_skip) {
		csi2->frame_skip--;
		if (csi2->frame_skip == 0) {
			ctx->format_id = csi2_ctx_map_format(csi2);
			csi2_ctx_config(csi2, ctx);
			csi2_ctx_enable(csi2, n, 1);
		}
		return;
	}

	if (csi2->output & CSI2_OUTPUT_MEMORY)
		csi2_isr_buffer(csi2);
}
예제 #2
0
파일: iss_csi2.c 프로젝트: MaxChina/linux
/*
 * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
 * @enable: Enable/disable CSI2 Context interrupts
 */
static void csi2_irq_ctx_set(struct iss_csi2_device *csi2, int enable)
{
	u32 reg = CSI2_CTX_IRQ_FE;
	int i;

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

	for (i = 0; i < 8; i++) {
		iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(i),
			      reg);
		if (enable)
			iss_reg_set(csi2->iss, csi2->regs1,
				    CSI2_CTX_IRQENABLE(i), reg);
		else
			iss_reg_clr(csi2->iss, csi2->regs1,
				    CSI2_CTX_IRQENABLE(i), reg);
	}
}
예제 #3
0
/*
 * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
 * @enable: Enable/disable CSI2 Context interrupts
 */
static void csi2_irq_ctx_set(struct iss_csi2_device *csi2, int enable)
{
	u32 reg = CSI2_CTX_IRQ_FE;
	int i;

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

	for (i = 0; i < 8; i++) {
		writel(reg, csi2->regs1 + CSI2_CTX_IRQSTATUS(i));
		if (enable)
			writel(readl(csi2->regs1 + CSI2_CTX_IRQENABLE(i)) | reg,
				csi2->regs1 + CSI2_CTX_IRQENABLE(i));
		else
			writel(readl(csi2->regs1 + CSI2_CTX_IRQENABLE(i)) &
				~reg,
				csi2->regs1 + CSI2_CTX_IRQENABLE(i));
	}
}