ENGR00315894-79 csi: Add csi module
Add csi module. Signed-off-by: Sandor Yu <R01008@freescale.com> Signed-off-by: Ye.Li <B37916@freescale.com> (cherry picked from commit 854ae26758ec8132ef749b98645dd2f43b84e5e2) Signed-off-by: Peng Fan <Peng.Fan@freescale.com> (cherry picked from commit 5f133bd9420109951fd03bd5168801327e929c3b) (cherry picked from commit 16960e59fa3334162d2e2212ee4bc1e7f0c420a3) (cherry picked from commit bc0639ed8f5069f198067916caf088908492329d)
This commit is contained in:
parent
99977a1152
commit
c7232ae1c2
|
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file fsl_csi.c, this file is derived from mx27_csi.c
|
||||
*
|
||||
* @brief mx25 CMOS Sensor interface functions
|
||||
*
|
||||
* @ingroup CSI
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include "mxc_csi.h"
|
||||
|
||||
enum {
|
||||
STD_NTSC = 0,
|
||||
STD_PAL,
|
||||
};
|
||||
|
||||
void __iomem *csi_regbase;
|
||||
|
||||
static void csihw_reset_frame_count(void)
|
||||
{
|
||||
__raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST, CSI_CSICR3);
|
||||
}
|
||||
|
||||
static void csihw_reset(void)
|
||||
{
|
||||
csihw_reset_frame_count();
|
||||
__raw_writel(CSICR1_RESET_VAL, CSI_CSICR1);
|
||||
__raw_writel(CSICR2_RESET_VAL, CSI_CSICR2);
|
||||
__raw_writel(CSICR3_RESET_VAL, CSI_CSICR3);
|
||||
}
|
||||
|
||||
/*!
|
||||
* csi_init_interface
|
||||
* Init csi interface
|
||||
*/
|
||||
void csi_init_interface(void)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
unsigned int imag_para;
|
||||
|
||||
val |= BIT_SOF_POL;
|
||||
val |= BIT_REDGE;
|
||||
val |= BIT_GCLK_MODE;
|
||||
val |= BIT_HSYNC_POL;
|
||||
val |= BIT_FCC;
|
||||
val |= 1 << SHIFT_MCLKDIV;
|
||||
val |= BIT_MCLKEN;
|
||||
__raw_writel(val, CSI_CSICR1);
|
||||
|
||||
imag_para = (640 << 16) | 960;
|
||||
__raw_writel(imag_para, CSI_CSIIMAG_PARA);
|
||||
|
||||
val = 0x1010;
|
||||
val |= BIT_DMA_REFLASH_RFF;
|
||||
__raw_writel(val, CSI_CSICR3);
|
||||
}
|
||||
|
||||
void csi_format_swap16(bool enable)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
val = __raw_readl(CSI_CSICR1);
|
||||
if (enable) {
|
||||
val |= BIT_PACK_DIR;
|
||||
val |= BIT_SWAP16_EN;
|
||||
} else {
|
||||
val &= ~BIT_PACK_DIR;
|
||||
val &= ~BIT_SWAP16_EN;
|
||||
}
|
||||
|
||||
__raw_writel(val, CSI_CSICR1);
|
||||
}
|
||||
|
||||
void csi_enable_int(int arg)
|
||||
{
|
||||
unsigned long cr1 = __raw_readl(CSI_CSICR1);
|
||||
|
||||
if (arg == 1) {
|
||||
/* still capture needs DMA intterrupt */
|
||||
cr1 |= BIT_FB1_DMA_DONE_INTEN;
|
||||
cr1 |= BIT_FB2_DMA_DONE_INTEN;
|
||||
}
|
||||
__raw_writel(cr1, CSI_CSICR1);
|
||||
}
|
||||
|
||||
void csi_disable_int(void)
|
||||
{
|
||||
unsigned long cr1 = __raw_readl(CSI_CSICR1);
|
||||
|
||||
cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
|
||||
cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
|
||||
__raw_writel(cr1, CSI_CSICR1);
|
||||
}
|
||||
|
||||
void csi_enable(int arg)
|
||||
{
|
||||
unsigned long cr = __raw_readl(CSI_CSICR18);
|
||||
|
||||
if (arg == 1)
|
||||
cr |= BIT_CSI_ENABLE;
|
||||
else
|
||||
cr &= ~BIT_CSI_ENABLE;
|
||||
__raw_writel(cr, CSI_CSICR18);
|
||||
}
|
||||
|
||||
void csi_buf_stride_set(u32 stride)
|
||||
{
|
||||
__raw_writel(stride, CSI_CSIFBUF_PARA);
|
||||
}
|
||||
|
||||
void csi_deinterlace_enable(bool enable)
|
||||
{
|
||||
unsigned long cr18 = __raw_readl(CSI_CSICR18);
|
||||
|
||||
if (enable == true)
|
||||
cr18 |= BIT_DEINTERLACE_EN;
|
||||
else
|
||||
cr18 &= ~BIT_DEINTERLACE_EN;
|
||||
|
||||
__raw_writel(cr18, CSI_CSICR18);
|
||||
}
|
||||
|
||||
void csi_deinterlace_mode(int mode)
|
||||
{
|
||||
unsigned long cr18 = __raw_readl(CSI_CSICR18);
|
||||
|
||||
if (mode == STD_NTSC)
|
||||
cr18 |= BIT_NTSC_EN;
|
||||
else
|
||||
cr18 &= ~BIT_NTSC_EN;
|
||||
|
||||
__raw_writel(cr18, CSI_CSICR18);
|
||||
}
|
||||
|
||||
void csi_tvdec_enable(bool enable)
|
||||
{
|
||||
unsigned long cr18 = __raw_readl(CSI_CSICR18);
|
||||
unsigned long cr1 = __raw_readl(CSI_CSICR1);
|
||||
|
||||
if (enable == true) {
|
||||
cr18 |= (BIT_TVDECODER_IN_EN | BIT_BASEADDR_SWITCH_EN);
|
||||
cr1 |= BIT_CCIR_MODE | BIT_EXT_VSYNC;
|
||||
cr1 &= ~(BIT_SOF_POL | BIT_REDGE);
|
||||
} else {
|
||||
cr18 &= ~(BIT_TVDECODER_IN_EN | BIT_BASEADDR_SWITCH_EN);
|
||||
cr1 &= ~(BIT_CCIR_MODE | BIT_EXT_VSYNC);
|
||||
cr1 |= BIT_SOF_POL | BIT_REDGE;
|
||||
}
|
||||
|
||||
__raw_writel(cr18, CSI_CSICR18);
|
||||
__raw_writel(cr1, CSI_CSICR1);
|
||||
}
|
||||
|
||||
void csi_set_32bit_imagpara(int width, int height)
|
||||
{
|
||||
int imag_para = 0;
|
||||
unsigned long cr3 = __raw_readl(CSI_CSICR3);
|
||||
|
||||
imag_para = (width << 16) | height;
|
||||
__raw_writel(imag_para, CSI_CSIIMAG_PARA);
|
||||
|
||||
|
||||
/* reflash the embeded DMA controller */
|
||||
__raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
|
||||
}
|
||||
|
||||
void csi_set_16bit_imagpara(int width, int height)
|
||||
{
|
||||
int imag_para = 0;
|
||||
unsigned long cr3 = __raw_readl(CSI_CSICR3);
|
||||
|
||||
imag_para = (width << 16) | (height * 2);
|
||||
__raw_writel(imag_para, CSI_CSIIMAG_PARA);
|
||||
|
||||
/* reflash the embeded DMA controller */
|
||||
__raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
|
||||
}
|
||||
|
||||
void csi_set_12bit_imagpara(int width, int height)
|
||||
{
|
||||
int imag_para = 0;
|
||||
unsigned long cr3 = __raw_readl(CSI_CSICR3);
|
||||
|
||||
imag_para = (width << 16) | (height * 3 / 2);
|
||||
__raw_writel(imag_para, CSI_CSIIMAG_PARA);
|
||||
|
||||
/* reflash the embeded DMA controller */
|
||||
__raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
|
||||
}
|
||||
|
||||
void csi_dmareq_rff_enable(void)
|
||||
{
|
||||
unsigned long cr3 = __raw_readl(CSI_CSICR3);
|
||||
|
||||
cr3 |= BIT_DMA_REQ_EN_RFF;
|
||||
cr3 |= BIT_HRESP_ERR_EN;
|
||||
__raw_writel(cr3, CSI_CSICR3);
|
||||
}
|
||||
|
||||
void csi_dmareq_rff_disable(void)
|
||||
{
|
||||
unsigned long cr3 = __raw_readl(CSI_CSICR3);
|
||||
|
||||
cr3 &= ~BIT_DMA_REQ_EN_RFF;
|
||||
cr3 &= ~BIT_HRESP_ERR_EN;
|
||||
__raw_writel(cr3, CSI_CSICR3);
|
||||
}
|
||||
|
||||
void csi_disable(void)
|
||||
{
|
||||
csi_dmareq_rff_disable();
|
||||
csi_disable_int();
|
||||
csi_buf_stride_set(0);
|
||||
csi_deinterlace_enable(false);
|
||||
csi_tvdec_enable(false);
|
||||
csi_enable(0);
|
||||
}
|
||||
|
||||
void csi_config(struct csi_conf_param *csi_conf)
|
||||
{
|
||||
csi_regbase = (u32 *)CSI1_BASE_ADDR;
|
||||
|
||||
csihw_reset();
|
||||
|
||||
csi_init_interface();
|
||||
csi_dmareq_rff_disable();
|
||||
|
||||
switch (csi_conf->bpp) {
|
||||
case 32:
|
||||
csi_set_32bit_imagpara(csi_conf->width, csi_conf->height);
|
||||
break;
|
||||
case 16:
|
||||
csi_set_16bit_imagpara(csi_conf->width, csi_conf->height);
|
||||
break;
|
||||
default:
|
||||
printf(" %s case not supported, bpp=%d\n",
|
||||
__func__, csi_conf->bpp);
|
||||
return;
|
||||
}
|
||||
|
||||
__raw_writel((u32)csi_conf->fb0addr, CSI_CSIDMASA_FB1);
|
||||
__raw_writel((u32)csi_conf->fb1addr, CSI_CSIDMASA_FB2);
|
||||
|
||||
csi_buf_stride_set(0);
|
||||
if (csi_conf->btvmode) {
|
||||
/* Enable csi PAL/NTSC deinterlace mode */
|
||||
csi_buf_stride_set(csi_conf->width);
|
||||
csi_deinterlace_mode(csi_conf->std);
|
||||
csi_deinterlace_enable(true);
|
||||
csi_tvdec_enable(true);
|
||||
}
|
||||
|
||||
/* start csi */
|
||||
csi_dmareq_rff_enable();
|
||||
csi_enable_int(1);
|
||||
csi_enable(1);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file mxc_csi.h
|
||||
*
|
||||
* @brief mxc CMOS Sensor interface functions
|
||||
*
|
||||
* @ingroup CSI
|
||||
*/
|
||||
|
||||
#ifndef MXC_CSI_H
|
||||
#define MXC_CSI_H
|
||||
|
||||
/* reset values */
|
||||
#define CSICR1_RESET_VAL 0x40000800
|
||||
#define CSICR2_RESET_VAL 0x0
|
||||
#define CSICR3_RESET_VAL 0x0
|
||||
|
||||
/* csi control reg 1 */
|
||||
#define BIT_SWAP16_EN (0x1 << 31)
|
||||
#define BIT_EXT_VSYNC (0x1 << 30)
|
||||
#define BIT_EOF_INT_EN (0x1 << 29)
|
||||
#define BIT_PRP_IF_EN (0x1 << 28)
|
||||
#define BIT_CCIR_MODE (0x1 << 27)
|
||||
#define BIT_COF_INT_EN (0x1 << 26)
|
||||
#define BIT_SF_OR_INTEN (0x1 << 25)
|
||||
#define BIT_RF_OR_INTEN (0x1 << 24)
|
||||
#define BIT_SFF_DMA_DONE_INTEN (0x1 << 22)
|
||||
#define BIT_STATFF_INTEN (0x1 << 21)
|
||||
#define BIT_FB2_DMA_DONE_INTEN (0x1 << 20)
|
||||
#define BIT_FB1_DMA_DONE_INTEN (0x1 << 19)
|
||||
#define BIT_RXFF_INTEN (0x1 << 18)
|
||||
#define BIT_SOF_POL (0x1 << 17)
|
||||
#define BIT_SOF_INTEN (0x1 << 16)
|
||||
#define BIT_MCLKDIV (0xF << 12)
|
||||
#define BIT_HSYNC_POL (0x1 << 11)
|
||||
#define BIT_CCIR_EN (0x1 << 10)
|
||||
#define BIT_MCLKEN (0x1 << 9)
|
||||
#define BIT_FCC (0x1 << 8)
|
||||
#define BIT_PACK_DIR (0x1 << 7)
|
||||
#define BIT_CLR_STATFIFO (0x1 << 6)
|
||||
#define BIT_CLR_RXFIFO (0x1 << 5)
|
||||
#define BIT_GCLK_MODE (0x1 << 4)
|
||||
#define BIT_INV_DATA (0x1 << 3)
|
||||
#define BIT_INV_PCLK (0x1 << 2)
|
||||
#define BIT_REDGE (0x1 << 1)
|
||||
#define BIT_PIXEL_BIT (0x1 << 0)
|
||||
|
||||
#define SHIFT_MCLKDIV 12
|
||||
|
||||
/* control reg 3 */
|
||||
#define BIT_FRMCNT (0xFFFF << 16)
|
||||
#define BIT_FRMCNT_RST (0x1 << 15)
|
||||
#define BIT_DMA_REFLASH_RFF (0x1 << 14)
|
||||
#define BIT_DMA_REFLASH_SFF (0x1 << 13)
|
||||
#define BIT_DMA_REQ_EN_RFF (0x1 << 12)
|
||||
#define BIT_DMA_REQ_EN_SFF (0x1 << 11)
|
||||
#define BIT_STATFF_LEVEL (0x7 << 8)
|
||||
#define BIT_HRESP_ERR_EN (0x1 << 7)
|
||||
#define BIT_RXFF_LEVEL (0x7 << 4)
|
||||
#define BIT_TWO_8BIT_SENSOR (0x1 << 3)
|
||||
#define BIT_ZERO_PACK_EN (0x1 << 2)
|
||||
#define BIT_ECC_INT_EN (0x1 << 1)
|
||||
#define BIT_ECC_AUTO_EN (0x1 << 0)
|
||||
|
||||
#define SHIFT_FRMCNT 16
|
||||
|
||||
/* csi status reg */
|
||||
#define BIT_SFF_OR_INT (0x1 << 25)
|
||||
#define BIT_RFF_OR_INT (0x1 << 24)
|
||||
#define BIT_DMA_TSF_DONE_SFF (0x1 << 22)
|
||||
#define BIT_STATFF_INT (0x1 << 21)
|
||||
#define BIT_DMA_TSF_DONE_FB2 (0x1 << 20)
|
||||
#define BIT_DMA_TSF_DONE_FB1 (0x1 << 19)
|
||||
#define BIT_RXFF_INT (0x1 << 18)
|
||||
#define BIT_EOF_INT (0x1 << 17)
|
||||
#define BIT_SOF_INT (0x1 << 16)
|
||||
#define BIT_F2_INT (0x1 << 15)
|
||||
#define BIT_F1_INT (0x1 << 14)
|
||||
#define BIT_COF_INT (0x1 << 13)
|
||||
#define BIT_HRESP_ERR_INT (0x1 << 7)
|
||||
#define BIT_ECC_INT (0x1 << 1)
|
||||
#define BIT_DRDY (0x1 << 0)
|
||||
|
||||
/* csi control reg 18 */
|
||||
#define BIT_CSI_ENABLE (0x1 << 31)
|
||||
#define BIT_BASEADDR_SWITCH_SEL (0x1 << 5)
|
||||
#define BIT_BASEADDR_SWITCH_EN (0x1 << 4)
|
||||
#define BIT_PARALLEL24_EN (0x1 << 3)
|
||||
#define BIT_DEINTERLACE_EN (0x1 << 2)
|
||||
#define BIT_TVDECODER_IN_EN (0x1 << 1)
|
||||
#define BIT_NTSC_EN (0x1 << 0)
|
||||
|
||||
#define CSI_MCLK_VF 1
|
||||
#define CSI_MCLK_ENC 2
|
||||
#define CSI_MCLK_RAW 4
|
||||
#define CSI_MCLK_I2C 8
|
||||
|
||||
#define CSI_CSICR1 (csi_regbase)
|
||||
#define CSI_CSICR2 (csi_regbase + 0x4)
|
||||
#define CSI_CSICR3 (csi_regbase + 0x8)
|
||||
#define CSI_STATFIFO (csi_regbase + 0xC)
|
||||
#define CSI_CSIRXFIFO (csi_regbase + 0x10)
|
||||
#define CSI_CSIRXCNT (csi_regbase + 0x14)
|
||||
#define CSI_CSISR (csi_regbase + 0x18)
|
||||
#define CSI_CSIDBG (csi_regbase + 0x1C)
|
||||
#define CSI_CSIDMASA_STATFIFO (csi_regbase + 0x20)
|
||||
#define CSI_CSIDMATS_STATFIFO (csi_regbase + 0x24)
|
||||
#define CSI_CSIDMASA_FB1 (csi_regbase + 0x28)
|
||||
#define CSI_CSIDMASA_FB2 (csi_regbase + 0x2C)
|
||||
#define CSI_CSIFBUF_PARA (csi_regbase + 0x30)
|
||||
#define CSI_CSIIMAG_PARA (csi_regbase + 0x34)
|
||||
#define CSI_CSICR18 (csi_regbase + 0x48)
|
||||
#define CSI_CSICR19 (csi_regbase + 0x4c)
|
||||
|
||||
struct mxs_csi_regs {
|
||||
u32 csi_csicr1; /* 0x0 */
|
||||
u32 csi_csicr2; /* 0x4 */
|
||||
u32 csi_csicr3; /* 0x8 */
|
||||
u32 csi_statfifo; /* 0xC */
|
||||
u32 csi_csirxfifo; /* 0x10 */
|
||||
u32 csi_csirxcnt; /* 0x14 */
|
||||
u32 csi_csisr; /* 0x18 */
|
||||
u32 csi_csidbg; /* 0x1C */
|
||||
u32 csi_csidmasa_statfifo; /* 0x20 */
|
||||
u32 csi_csidmats_statfifo; /* 0x24 */
|
||||
u32 csi_csidmasa_fb1; /* 0x28 */
|
||||
u32 csi_csidmasa_fb2; /* 0x2C */
|
||||
u32 csi_csifbuf_para; /* 0x30 */
|
||||
u32 csi_csiimag_para; /* 0x34 */
|
||||
u32 reserver[4];
|
||||
u32 csi_csicr18; /* 0x48 */
|
||||
u32 csi_csicr19; /* 0x4c */
|
||||
};
|
||||
|
||||
struct csi_conf_param {
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
unsigned int pixel_fmt;
|
||||
unsigned int bpp;
|
||||
bool btvmode;
|
||||
unsigned int std;
|
||||
void *fb0addr;
|
||||
void *fb1addr;
|
||||
};
|
||||
|
||||
void csi_config(struct csi_conf_param *csi_conf);
|
||||
void csi_disable(void);
|
||||
#endif
|
||||
Loading…
Reference in New Issue