Esempio n. 1
0
static void omap24xxcam_dmahw_init(void __iomem *base)
{
	omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG,
			    CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY
			    | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE
			    | CAMDMA_OCP_SYSCONFIG_AUTOIDLE);

	omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10,
			      CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH);

	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xf);
}
Esempio n. 2
0
/* Ack dmach on CSR and IRQSTATUS_L0 */
static u32 omap24xxcam_dmahw_ack_ch(void __iomem *base, int dmach)
{
	u32 csr;

	csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
	/* ack interrupt in CSR */
	omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
	/* ack interrupt in IRQSTATUS */
	omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));

	return csr;
}
Esempio n. 3
0
/* Ack all interrupt on CSR and IRQSTATUS_L0 */
static void omap24xxcam_dmahw_ack_all(void __iomem *base)
{
	u32 csr;
	int i;

	for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) {
		csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
		/* ack interrupt in CSR */
		omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
	}
	omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf);
}
Esempio n. 4
0
static u32 omap24xxcam_dmahw_ack_ch(unsigned long base, int dmach)
{
	u32 csr;

	csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
	
	omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
	
	omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));

	return csr;
}
Esempio n. 5
0
static void omap24xxcam_dmahw_ack_all(unsigned long base)
{
	u32 csr;
	int i;

	for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) {
		csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
		
		omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
	}
	omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf);
}
Esempio n. 6
0
static void omap24xxcam_dmahw_transfer_chain(void __iomem *base, int dmach,
					     int free_dmach)
{
	int prev_dmach, ch;

	if (dmach == 0)
		prev_dmach = NUM_CAMDMA_CHANNELS - 1;
	else
		prev_dmach = dmach - 1;
	omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach),
			    CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach);
	/* Did we chain the DMA transfer before the previous one
	 * finished?
	 */
	ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS;
	while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch))
		 & CAMDMA_CCR_ENABLE)) {
		if (ch == dmach) {
			/* The previous transfer has ended and this one
			 * hasn't started, so we must not have chained
			 * to the previous one in time.  We'll have to
			 * start it now.
			 */
			omap24xxcam_dmahw_transfer_start(base, dmach);
			break;
		} else
			ch = (ch + 1) % NUM_CAMDMA_CHANNELS;
	}
}
Esempio n. 7
0
/*
 * (Re)initialise the camera block.
 */
static void omap24xxcam_hwinit(struct omap24xxcam_device *cam)
{
	omap24xxcam_poweron_reset(cam);

	/* set the camera subsystem autoidle bit */
	omap24xxcam_reg_out(cam->mmio_base, CAM_SYSCONFIG,
			    CAM_SYSCONFIG_AUTOIDLE);

	/* set the camera MMU autoidle bit */
	omap24xxcam_reg_out(cam->mmio_base,
			    CAMMMU_REG_OFFSET + CAMMMU_SYSCONFIG,
			    CAMMMU_SYSCONFIG_AUTOIDLE);

	omap24xxcam_core_hwinit(cam);

	omap24xxcam_dma_hwinit(&cam->sgdma.dma);
}
Esempio n. 8
0
/*
 * Set xclk.
 *
 * To disable xclk, use value zero.
 */
static void omap24xxcam_core_xclk_set(const struct omap24xxcam_device *cam,
				      u32 xclk)
{
	if (xclk) {
		u32 divisor = CAM_MCLK / xclk;

		if (divisor == 1)
			omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
					    CC_CTRL_XCLK,
					    CC_CTRL_XCLK_DIV_BYPASS);
		else
			omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
					    CC_CTRL_XCLK, divisor);
	} else
		omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
				    CC_CTRL_XCLK, CC_CTRL_XCLK_DIV_STABLE_LOW);
}
Esempio n. 9
0
static void omap24xxcam_dmahw_abort_ch(unsigned long base, int dmach)
{
	
	omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
	
	omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0,
			      CAMDMA_CLNK_CTRL_ENABLE_LNK);
	
	omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE);
}
Esempio n. 10
0
/* Abort all chained DMA transfers. After all transfers have been
 * aborted and the DMA controller is idle, the completion routines for
 * any aborted transfers will be called in sequence. The DMA
 * controller may not be idle after this routine completes, because
 * the completion routines might start new transfers.
 */
static void omap24xxcam_dmahw_abort_ch(void __iomem *base, int dmach)
{
	/* mask all interrupts from this channel */
	omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
	/* unlink this channel */
	omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0,
			      CAMDMA_CLNK_CTRL_ENABLE_LNK);
	/* disable this channel */
	omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE);
}
Esempio n. 11
0
static void omap24xxcam_dmahw_transfer_start(void __iomem *base, int dmach)
{
	omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
			    CAMDMA_CCR_SEL_SRC_DST_SYNC
			    | CAMDMA_CCR_BS
			    | CAMDMA_CCR_DST_AMODE_POST_INC
			    | CAMDMA_CCR_SRC_AMODE_POST_INC
			    | CAMDMA_CCR_ENABLE
			    | CAMDMA_CCR_FS
			    | CAMDMA_CCR_SYNCHRO_CAMERA);
}
Esempio n. 12
0
static void omap24xxcam_core_hwinit(const struct omap24xxcam_device *cam)
{
	/*
	 * Setting the camera core AUTOIDLE bit causes problems with frame
	 * synchronization, so we will clear the AUTOIDLE bit instead.
	 */
	omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_SYSCONFIG,
			    CC_SYSCONFIG_AUTOIDLE);

	/* program the camera interface DMA packet size */
	omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL_DMA,
			    CC_CTRL_DMA_EN | (DMA_THRESHOLD / 4 - 1));

	/* enable camera core error interrupts */
	omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQENABLE,
			    CC_IRQENABLE_FW_ERR_IRQ
			    | CC_IRQENABLE_FSC_ERR_IRQ
			    | CC_IRQENABLE_SSC_ERR_IRQ
			    | CC_IRQENABLE_FIFO_OF_IRQ);
}
Esempio n. 13
0
/*
 * Reset camera block to power-on state.
 */
static void omap24xxcam_poweron_reset(struct omap24xxcam_device *cam)
{
	int max_loop = RESET_TIMEOUT_NS;

	/* Reset whole camera subsystem */
	omap24xxcam_reg_out(cam->mmio_base,
			    CAM_SYSCONFIG,
			    CAM_SYSCONFIG_SOFTRESET);

	/* Wait till it's finished */
	while (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
		 & CAM_SYSSTATUS_RESETDONE)
	       && --max_loop) {
		ndelay(1);
	}

	if (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
	      & CAM_SYSSTATUS_RESETDONE))
		dev_err(cam->dev, "camera soft reset timeout\n");
}
Esempio n. 14
0
/* Interrupt service routine for camera core interrupts. */
static void omap24xxcam_core_isr(struct omap24xxcam_device *cam)
{
	u32 cc_irqstatus;
	const u32 cc_irqstatus_err =
		CC_IRQSTATUS_FW_ERR_IRQ
		| CC_IRQSTATUS_FSC_ERR_IRQ
		| CC_IRQSTATUS_SSC_ERR_IRQ
		| CC_IRQSTATUS_FIFO_UF_IRQ
		| CC_IRQSTATUS_FIFO_OF_IRQ;

	cc_irqstatus = omap24xxcam_reg_in(cam->mmio_base + CC_REG_OFFSET,
					  CC_IRQSTATUS);
	omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQSTATUS,
			    cc_irqstatus);

	if (cc_irqstatus & cc_irqstatus_err
	    && !atomic_read(&cam->in_reset)) {
		dev_dbg(cam->dev, "resetting camera, cc_irqstatus 0x%x\n",
			cc_irqstatus);
		omap24xxcam_reset(cam);
	}
}
Esempio n. 15
0
static void omap24xxcam_dmahw_transfer_chain(unsigned long base, int dmach,
					     int free_dmach)
{
	int prev_dmach, ch;

	if (dmach == 0)
		prev_dmach = NUM_CAMDMA_CHANNELS - 1;
	else
		prev_dmach = dmach - 1;
	omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach),
			    CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach);
	
	ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS;
	while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch))
		 & CAMDMA_CCR_ENABLE)) {
		if (ch == dmach) {
			
			omap24xxcam_dmahw_transfer_start(base, dmach);
			break;
		} else
			ch = (ch + 1) % NUM_CAMDMA_CHANNELS;
	}
}
Esempio n. 16
0
static void omap24xxcam_dmahw_transfer_setup(void __iomem *base, int dmach,
					     dma_addr_t start, u32 len)
{
	omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
			    CAMDMA_CCR_SEL_SRC_DST_SYNC
			    | CAMDMA_CCR_BS
			    | CAMDMA_CCR_DST_AMODE_POST_INC
			    | CAMDMA_CCR_SRC_AMODE_POST_INC
			    | CAMDMA_CCR_FS
			    | CAMDMA_CCR_WR_ACTIVE
			    | CAMDMA_CCR_RD_ACTIVE
			    | CAMDMA_CCR_SYNCHRO_CAMERA);
	omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len);
	omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1);
	omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach),
			    CAMDMA_CSDP_WRITE_MODE_POSTED
			    | CAMDMA_CSDP_DST_BURST_EN_32
			    | CAMDMA_CSDP_DST_PACKED
			    | CAMDMA_CSDP_SRC_BURST_EN_32
			    | CAMDMA_CSDP_SRC_PACKED
			    | CAMDMA_CSDP_DATA_TYPE_8BITS);
	omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start);
	omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD);
	omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CSR(dmach),
			    CAMDMA_CSR_MISALIGNED_ERR
			    | CAMDMA_CSR_SECURE_ERR
			    | CAMDMA_CSR_TRANS_ERR
			    | CAMDMA_CSR_BLOCK
			    | CAMDMA_CSR_DROP);
	omap24xxcam_reg_out(base, CAMDMA_CICR(dmach),
			    CAMDMA_CICR_MISALIGNED_ERR_IE
			    | CAMDMA_CICR_SECURE_ERR_IE
			    | CAMDMA_CICR_TRANS_ERR_IE
			    | CAMDMA_CICR_BLOCK_IE
			    | CAMDMA_CICR_DROP_IE);
}
Esempio n. 17
0
/*
 * Enable the camera core.
 *
 * Data transfer to the camera DMA starts from next starting frame.
 */
static void omap24xxcam_core_enable(const struct omap24xxcam_device *cam)
{

	omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL,
			    cam->cc_ctrl);
}
Esempio n. 18
0
/*
 * Disable camera core.
 *
 * The data transfer will be stopped immediately (CC_CTRL_CC_RST). The
 * core internal state machines will be reset. Use
 * CC_CTRL_CC_FRAME_TRIG instead if you want to transfer the current
 * frame completely.
 */
static void omap24xxcam_core_disable(const struct omap24xxcam_device *cam)
{
	omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL,
			    CC_CTRL_CC_RST);
}