Commit 8c1ddd0bb85574250cc2c1536bedc66b6cd3faa1

Authored by Ye.Li
Committed by Ye Li
1 parent fc8b1ea936

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)
(cherry picked from commit c7232ae1c27ef561d2235bb4db837ef9805f86d2)
(cherry picked from commit 039bb76082a16b0e43e818a4d9df68ab4320ede5)
(cherry picked from commit 4048b2cc1932a51f7f8c32ddf21bcf5ebd885a4f)

Showing 2 changed files with 425 additions and 0 deletions Side-by-side Diff

drivers/video/mxc_csi.c
  1 +/* SPDX-License-Identifier: GPL-2.0+ */
  2 +/*
  3 + * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  4 + *
  5 + */
  6 +
  7 +/*!
  8 + * @file fsl_csi.c, this file is derived from mx27_csi.c
  9 + *
  10 + * @brief mx25 CMOS Sensor interface functions
  11 + *
  12 + * @ingroup CSI
  13 + */
  14 +#include <common.h>
  15 +#include <malloc.h>
  16 +
  17 +#include <asm/arch/imx-regs.h>
  18 +#include <linux/errno.h>
  19 +#include <asm/io.h>
  20 +
  21 +#include <linux/string.h>
  22 +#include <linux/list.h>
  23 +
  24 +#include "mxc_csi.h"
  25 +
  26 +enum {
  27 + STD_NTSC = 0,
  28 + STD_PAL,
  29 +};
  30 +
  31 +void __iomem *csi_regbase;
  32 +
  33 +static void csihw_reset_frame_count(void)
  34 +{
  35 + __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST, CSI_CSICR3);
  36 +}
  37 +
  38 +static void csihw_reset(void)
  39 +{
  40 + csihw_reset_frame_count();
  41 + __raw_writel(CSICR1_RESET_VAL, CSI_CSICR1);
  42 + __raw_writel(CSICR2_RESET_VAL, CSI_CSICR2);
  43 + __raw_writel(CSICR3_RESET_VAL, CSI_CSICR3);
  44 +}
  45 +
  46 +/*!
  47 + * csi_init_interface
  48 + * Init csi interface
  49 + */
  50 +void csi_init_interface(void)
  51 +{
  52 + unsigned int val = 0;
  53 + unsigned int imag_para;
  54 +
  55 + val |= BIT_SOF_POL;
  56 + val |= BIT_REDGE;
  57 + val |= BIT_GCLK_MODE;
  58 + val |= BIT_HSYNC_POL;
  59 + val |= BIT_FCC;
  60 + val |= 1 << SHIFT_MCLKDIV;
  61 + val |= BIT_MCLKEN;
  62 + __raw_writel(val, CSI_CSICR1);
  63 +
  64 + imag_para = (640 << 16) | 960;
  65 + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  66 +
  67 + val = 0x1010;
  68 + val |= BIT_DMA_REFLASH_RFF;
  69 + __raw_writel(val, CSI_CSICR3);
  70 +}
  71 +
  72 +void csi_format_swap16(bool enable)
  73 +{
  74 + unsigned int val;
  75 +
  76 + val = __raw_readl(CSI_CSICR1);
  77 + if (enable) {
  78 + val |= BIT_PACK_DIR;
  79 + val |= BIT_SWAP16_EN;
  80 + } else {
  81 + val &= ~BIT_PACK_DIR;
  82 + val &= ~BIT_SWAP16_EN;
  83 + }
  84 +
  85 + __raw_writel(val, CSI_CSICR1);
  86 +}
  87 +
  88 +void csi_enable_int(int arg)
  89 +{
  90 + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  91 +
  92 + if (arg == 1) {
  93 + /* still capture needs DMA intterrupt */
  94 + cr1 |= BIT_FB1_DMA_DONE_INTEN;
  95 + cr1 |= BIT_FB2_DMA_DONE_INTEN;
  96 + }
  97 + __raw_writel(cr1, CSI_CSICR1);
  98 +}
  99 +
  100 +void csi_disable_int(void)
  101 +{
  102 + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  103 +
  104 + cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
  105 + cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
  106 + __raw_writel(cr1, CSI_CSICR1);
  107 +}
  108 +
  109 +void csi_enable(int arg)
  110 +{
  111 + unsigned long cr = __raw_readl(CSI_CSICR18);
  112 +
  113 + if (arg == 1)
  114 + cr |= BIT_CSI_ENABLE;
  115 + else
  116 + cr &= ~BIT_CSI_ENABLE;
  117 + __raw_writel(cr, CSI_CSICR18);
  118 +}
  119 +
  120 +void csi_buf_stride_set(u32 stride)
  121 +{
  122 + __raw_writel(stride, CSI_CSIFBUF_PARA);
  123 +}
  124 +
  125 +void csi_deinterlace_enable(bool enable)
  126 +{
  127 + unsigned long cr18 = __raw_readl(CSI_CSICR18);
  128 +
  129 + if (enable == true)
  130 + cr18 |= BIT_DEINTERLACE_EN;
  131 + else
  132 + cr18 &= ~BIT_DEINTERLACE_EN;
  133 +
  134 + __raw_writel(cr18, CSI_CSICR18);
  135 +}
  136 +
  137 +void csi_deinterlace_mode(int mode)
  138 +{
  139 + unsigned long cr18 = __raw_readl(CSI_CSICR18);
  140 +
  141 + if (mode == STD_NTSC)
  142 + cr18 |= BIT_NTSC_EN;
  143 + else
  144 + cr18 &= ~BIT_NTSC_EN;
  145 +
  146 + __raw_writel(cr18, CSI_CSICR18);
  147 +}
  148 +
  149 +void csi_tvdec_enable(bool enable)
  150 +{
  151 + unsigned long cr18 = __raw_readl(CSI_CSICR18);
  152 + unsigned long cr1 = __raw_readl(CSI_CSICR1);
  153 +
  154 + if (enable == true) {
  155 + cr18 |= (BIT_TVDECODER_IN_EN | BIT_BASEADDR_SWITCH_EN);
  156 + cr1 |= BIT_CCIR_MODE | BIT_EXT_VSYNC;
  157 + cr1 &= ~(BIT_SOF_POL | BIT_REDGE);
  158 + } else {
  159 + cr18 &= ~(BIT_TVDECODER_IN_EN | BIT_BASEADDR_SWITCH_EN);
  160 + cr1 &= ~(BIT_CCIR_MODE | BIT_EXT_VSYNC);
  161 + cr1 |= BIT_SOF_POL | BIT_REDGE;
  162 + }
  163 +
  164 + __raw_writel(cr18, CSI_CSICR18);
  165 + __raw_writel(cr1, CSI_CSICR1);
  166 +}
  167 +
  168 +void csi_set_32bit_imagpara(int width, int height)
  169 +{
  170 + int imag_para = 0;
  171 + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  172 +
  173 + imag_para = (width << 16) | height;
  174 + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  175 +
  176 +
  177 + /* reflash the embeded DMA controller */
  178 + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  179 +}
  180 +
  181 +void csi_set_16bit_imagpara(int width, int height)
  182 +{
  183 + int imag_para = 0;
  184 + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  185 +
  186 + imag_para = (width << 16) | (height * 2);
  187 + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  188 +
  189 + /* reflash the embeded DMA controller */
  190 + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  191 +}
  192 +
  193 +void csi_set_12bit_imagpara(int width, int height)
  194 +{
  195 + int imag_para = 0;
  196 + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  197 +
  198 + imag_para = (width << 16) | (height * 3 / 2);
  199 + __raw_writel(imag_para, CSI_CSIIMAG_PARA);
  200 +
  201 + /* reflash the embeded DMA controller */
  202 + __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
  203 +}
  204 +
  205 +void csi_dmareq_rff_enable(void)
  206 +{
  207 + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  208 +
  209 + cr3 |= BIT_DMA_REQ_EN_RFF;
  210 + cr3 |= BIT_HRESP_ERR_EN;
  211 + __raw_writel(cr3, CSI_CSICR3);
  212 +}
  213 +
  214 +void csi_dmareq_rff_disable(void)
  215 +{
  216 + unsigned long cr3 = __raw_readl(CSI_CSICR3);
  217 +
  218 + cr3 &= ~BIT_DMA_REQ_EN_RFF;
  219 + cr3 &= ~BIT_HRESP_ERR_EN;
  220 + __raw_writel(cr3, CSI_CSICR3);
  221 +}
  222 +
  223 +void csi_disable(void)
  224 +{
  225 + csi_dmareq_rff_disable();
  226 + csi_disable_int();
  227 + csi_buf_stride_set(0);
  228 + csi_deinterlace_enable(false);
  229 + csi_tvdec_enable(false);
  230 + csi_enable(0);
  231 +}
  232 +
  233 +void csi_config(struct csi_conf_param *csi_conf)
  234 +{
  235 + csi_regbase = (u32 *)CSI1_BASE_ADDR;
  236 +
  237 + csihw_reset();
  238 +
  239 + csi_init_interface();
  240 + csi_dmareq_rff_disable();
  241 +
  242 + switch (csi_conf->bpp) {
  243 + case 32:
  244 + csi_set_32bit_imagpara(csi_conf->width, csi_conf->height);
  245 + break;
  246 + case 16:
  247 + csi_set_16bit_imagpara(csi_conf->width, csi_conf->height);
  248 + break;
  249 + default:
  250 + printf(" %s case not supported, bpp=%d\n",
  251 + __func__, csi_conf->bpp);
  252 + return;
  253 + }
  254 +
  255 + __raw_writel((u32)csi_conf->fb0addr, CSI_CSIDMASA_FB1);
  256 + __raw_writel((u32)csi_conf->fb1addr, CSI_CSIDMASA_FB2);
  257 +
  258 + csi_buf_stride_set(0);
  259 + if (csi_conf->btvmode) {
  260 + /* Enable csi PAL/NTSC deinterlace mode */
  261 + csi_buf_stride_set(csi_conf->width);
  262 + csi_deinterlace_mode(csi_conf->std);
  263 + csi_deinterlace_enable(true);
  264 + csi_tvdec_enable(true);
  265 + }
  266 +
  267 + /* start csi */
  268 + csi_dmareq_rff_enable();
  269 + csi_enable_int(1);
  270 + csi_enable(1);
  271 +}
drivers/video/mxc_csi.h
  1 +/* SPDX-License-Identifier: GPL-2.0+ */
  2 +/*
  3 + * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
  4 + *
  5 + */
  6 +
  7 +/*!
  8 + * @file mxc_csi.h
  9 + *
  10 + * @brief mxc CMOS Sensor interface functions
  11 + *
  12 + * @ingroup CSI
  13 + */
  14 +
  15 +#ifndef MXC_CSI_H
  16 +#define MXC_CSI_H
  17 +
  18 +/* reset values */
  19 +#define CSICR1_RESET_VAL 0x40000800
  20 +#define CSICR2_RESET_VAL 0x0
  21 +#define CSICR3_RESET_VAL 0x0
  22 +
  23 +/* csi control reg 1 */
  24 +#define BIT_SWAP16_EN (0x1 << 31)
  25 +#define BIT_EXT_VSYNC (0x1 << 30)
  26 +#define BIT_EOF_INT_EN (0x1 << 29)
  27 +#define BIT_PRP_IF_EN (0x1 << 28)
  28 +#define BIT_CCIR_MODE (0x1 << 27)
  29 +#define BIT_COF_INT_EN (0x1 << 26)
  30 +#define BIT_SF_OR_INTEN (0x1 << 25)
  31 +#define BIT_RF_OR_INTEN (0x1 << 24)
  32 +#define BIT_SFF_DMA_DONE_INTEN (0x1 << 22)
  33 +#define BIT_STATFF_INTEN (0x1 << 21)
  34 +#define BIT_FB2_DMA_DONE_INTEN (0x1 << 20)
  35 +#define BIT_FB1_DMA_DONE_INTEN (0x1 << 19)
  36 +#define BIT_RXFF_INTEN (0x1 << 18)
  37 +#define BIT_SOF_POL (0x1 << 17)
  38 +#define BIT_SOF_INTEN (0x1 << 16)
  39 +#define BIT_MCLKDIV (0xF << 12)
  40 +#define BIT_HSYNC_POL (0x1 << 11)
  41 +#define BIT_CCIR_EN (0x1 << 10)
  42 +#define BIT_MCLKEN (0x1 << 9)
  43 +#define BIT_FCC (0x1 << 8)
  44 +#define BIT_PACK_DIR (0x1 << 7)
  45 +#define BIT_CLR_STATFIFO (0x1 << 6)
  46 +#define BIT_CLR_RXFIFO (0x1 << 5)
  47 +#define BIT_GCLK_MODE (0x1 << 4)
  48 +#define BIT_INV_DATA (0x1 << 3)
  49 +#define BIT_INV_PCLK (0x1 << 2)
  50 +#define BIT_REDGE (0x1 << 1)
  51 +#define BIT_PIXEL_BIT (0x1 << 0)
  52 +
  53 +#define SHIFT_MCLKDIV 12
  54 +
  55 +/* control reg 3 */
  56 +#define BIT_FRMCNT (0xFFFF << 16)
  57 +#define BIT_FRMCNT_RST (0x1 << 15)
  58 +#define BIT_DMA_REFLASH_RFF (0x1 << 14)
  59 +#define BIT_DMA_REFLASH_SFF (0x1 << 13)
  60 +#define BIT_DMA_REQ_EN_RFF (0x1 << 12)
  61 +#define BIT_DMA_REQ_EN_SFF (0x1 << 11)
  62 +#define BIT_STATFF_LEVEL (0x7 << 8)
  63 +#define BIT_HRESP_ERR_EN (0x1 << 7)
  64 +#define BIT_RXFF_LEVEL (0x7 << 4)
  65 +#define BIT_TWO_8BIT_SENSOR (0x1 << 3)
  66 +#define BIT_ZERO_PACK_EN (0x1 << 2)
  67 +#define BIT_ECC_INT_EN (0x1 << 1)
  68 +#define BIT_ECC_AUTO_EN (0x1 << 0)
  69 +
  70 +#define SHIFT_FRMCNT 16
  71 +
  72 +/* csi status reg */
  73 +#define BIT_SFF_OR_INT (0x1 << 25)
  74 +#define BIT_RFF_OR_INT (0x1 << 24)
  75 +#define BIT_DMA_TSF_DONE_SFF (0x1 << 22)
  76 +#define BIT_STATFF_INT (0x1 << 21)
  77 +#define BIT_DMA_TSF_DONE_FB2 (0x1 << 20)
  78 +#define BIT_DMA_TSF_DONE_FB1 (0x1 << 19)
  79 +#define BIT_RXFF_INT (0x1 << 18)
  80 +#define BIT_EOF_INT (0x1 << 17)
  81 +#define BIT_SOF_INT (0x1 << 16)
  82 +#define BIT_F2_INT (0x1 << 15)
  83 +#define BIT_F1_INT (0x1 << 14)
  84 +#define BIT_COF_INT (0x1 << 13)
  85 +#define BIT_HRESP_ERR_INT (0x1 << 7)
  86 +#define BIT_ECC_INT (0x1 << 1)
  87 +#define BIT_DRDY (0x1 << 0)
  88 +
  89 +/* csi control reg 18 */
  90 +#define BIT_CSI_ENABLE (0x1 << 31)
  91 +#define BIT_BASEADDR_SWITCH_SEL (0x1 << 5)
  92 +#define BIT_BASEADDR_SWITCH_EN (0x1 << 4)
  93 +#define BIT_PARALLEL24_EN (0x1 << 3)
  94 +#define BIT_DEINTERLACE_EN (0x1 << 2)
  95 +#define BIT_TVDECODER_IN_EN (0x1 << 1)
  96 +#define BIT_NTSC_EN (0x1 << 0)
  97 +
  98 +#define CSI_MCLK_VF 1
  99 +#define CSI_MCLK_ENC 2
  100 +#define CSI_MCLK_RAW 4
  101 +#define CSI_MCLK_I2C 8
  102 +
  103 +#define CSI_CSICR1 (csi_regbase)
  104 +#define CSI_CSICR2 (csi_regbase + 0x4)
  105 +#define CSI_CSICR3 (csi_regbase + 0x8)
  106 +#define CSI_STATFIFO (csi_regbase + 0xC)
  107 +#define CSI_CSIRXFIFO (csi_regbase + 0x10)
  108 +#define CSI_CSIRXCNT (csi_regbase + 0x14)
  109 +#define CSI_CSISR (csi_regbase + 0x18)
  110 +#define CSI_CSIDBG (csi_regbase + 0x1C)
  111 +#define CSI_CSIDMASA_STATFIFO (csi_regbase + 0x20)
  112 +#define CSI_CSIDMATS_STATFIFO (csi_regbase + 0x24)
  113 +#define CSI_CSIDMASA_FB1 (csi_regbase + 0x28)
  114 +#define CSI_CSIDMASA_FB2 (csi_regbase + 0x2C)
  115 +#define CSI_CSIFBUF_PARA (csi_regbase + 0x30)
  116 +#define CSI_CSIIMAG_PARA (csi_regbase + 0x34)
  117 +#define CSI_CSICR18 (csi_regbase + 0x48)
  118 +#define CSI_CSICR19 (csi_regbase + 0x4c)
  119 +
  120 +struct mxs_csi_regs {
  121 + u32 csi_csicr1; /* 0x0 */
  122 + u32 csi_csicr2; /* 0x4 */
  123 + u32 csi_csicr3; /* 0x8 */
  124 + u32 csi_statfifo; /* 0xC */
  125 + u32 csi_csirxfifo; /* 0x10 */
  126 + u32 csi_csirxcnt; /* 0x14 */
  127 + u32 csi_csisr; /* 0x18 */
  128 + u32 csi_csidbg; /* 0x1C */
  129 + u32 csi_csidmasa_statfifo; /* 0x20 */
  130 + u32 csi_csidmats_statfifo; /* 0x24 */
  131 + u32 csi_csidmasa_fb1; /* 0x28 */
  132 + u32 csi_csidmasa_fb2; /* 0x2C */
  133 + u32 csi_csifbuf_para; /* 0x30 */
  134 + u32 csi_csiimag_para; /* 0x34 */
  135 + u32 reserver[4];
  136 + u32 csi_csicr18; /* 0x48 */
  137 + u32 csi_csicr19; /* 0x4c */
  138 +};
  139 +
  140 +struct csi_conf_param {
  141 + unsigned short width;
  142 + unsigned short height;
  143 + unsigned int pixel_fmt;
  144 + unsigned int bpp;
  145 + bool btvmode;
  146 + unsigned int std;
  147 + void *fb0addr;
  148 + void *fb1addr;
  149 +};
  150 +
  151 +void csi_config(struct csi_conf_param *csi_conf);
  152 +void csi_disable(void);
  153 +#endif