From: Sergio Aguirre <[EMAIL PROTECTED]>

OMAP: CAM: Add CSI2 changes to ISP driver

This adds CSI2 related changes to the ISP driver.

Signed-off-by: Sergio Aguirre <[EMAIL PROTECTED]>
---
 drivers/media/video/isp/isp.c        |   96 ++++++++++++++++++++++++++++-------
 drivers/media/video/isp/isp.h        |   13 ++++
 drivers/media/video/isp/ispccdc.c    |   40 +++++++++++---
 drivers/media/video/isp/ispccdc.h    |    2 
 drivers/media/video/isp/isppreview.c |   27 ++++++++-
 drivers/media/video/isp/isppreview.h |    2 
 6 files changed, 151 insertions(+), 29 deletions(-)

Index: omapkernel/drivers/media/video/isp/isp.c
===================================================================
--- omapkernel.orig/drivers/media/video/isp/isp.c       2008-10-15 
20:08:34.000000000 -0500
+++ omapkernel/drivers/media/video/isp/isp.c    2008-10-15 20:08:36.000000000 
-0500
@@ -48,6 +48,7 @@
 #include "isp_af.h"
 #include "isppreview.h"
 #include "ispresizer.h"
+#include "ispcsi2.h"
 
 #if ISP_WORKAROUND
 void *buff_addr;
@@ -171,6 +172,7 @@
        int ref_count;
        struct clk *cam_ick;
        struct clk *cam_mclk;
+       struct clk *csi2_fck;
 } isp_obj;
 
 struct isp_sgdma ispsg;
@@ -528,6 +530,14 @@
                                        IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ),
                                        ISP_IRQ0ENABLE);
                break;
+       case CBK_CSIA:
+               isp_csi2_irq_set(0);
+               break;
+       case CBK_CSIB:
+               omap_writel(IRQ0ENABLE_CSIB_IRQ, ISP_IRQ0STATUS);
+               omap_writel(omap_readl(ISP_IRQ0ENABLE)|IRQ0ENABLE_CSIB_IRQ,
+                                       ISP_IRQ0ENABLE);
+               break;
        default:
                break;
        }
@@ -892,6 +902,29 @@
                ispctrl_val |= (config->u.par.par_bridge
                                                << ISPCTRL_PAR_BRIDGE_SHIFT);
                break;
+       case ISP_CSIA:
+               ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIA;
+               ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_BENDIAN;
+               ispctrl_val |= (0x03 << ISPCTRL_PAR_BRIDGE_SHIFT);
+
+               isp_csi2_ctx_config_format(0, config->u.csi.format);
+               isp_csi2_ctx_update(0, false);
+
+               if (config->u.csi.crc)
+                       isp_csi2_ctrl_config_ecc_enable(true);
+
+               isp_csi2_ctrl_config_vp_out_ctrl(config->u.csi.vpclk);
+               isp_csi2_ctrl_config_vp_only_enable(true);
+               isp_csi2_ctrl_config_vp_clk_enable(true);
+               isp_csi2_ctrl_update(false);
+
+               isp_csi2_irq_complexio1_set(1);
+               isp_csi2_irq_status_set(1);
+               isp_csi2_irq_set(1);
+
+               isp_csi2_enable(1);
+               mdelay(3);
+               break;
        case ISP_CSIB:
                ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIB;
                r = isp_init_csi(config);
@@ -915,11 +948,32 @@
                                                ISPCCDC_VDINT_1_SHIFT),
                                                ISPCCDC_VDINT);
 
+       /* Set sensor specific fields in CCDC and Previewer module.*/
+       isppreview_set_skip(config->prev_sph, config->prev_slv);
+       ispccdc_set_wenlog(config->wenlog);
+
        return 0;
 }
 EXPORT_SYMBOL(isp_configure_interface);
 
 /**
+ * isp_configure_interface_bridge - Configure CCDC i/f bridge.
+ *
+ * Sets the bit field that controls the 8 to 16-bit bridge at
+ * the input to CCDC.
+ **/
+int isp_configure_interface_bridge(u32 par_bridge)
+{
+       u32 ispctrl_val = omap_readl(ISP_CTRL);
+
+       ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_BENDIAN;
+       ispctrl_val |= (par_bridge << ISPCTRL_PAR_BRIDGE_SHIFT);
+       omap_writel(ispctrl_val, ISP_CTRL);
+       return 0;
+}
+EXPORT_SYMBOL(isp_configure_interface_bridge);
+
+/**
  * isp_CCDC_VD01_enable - Enables VD0 and VD1 IRQs.
  *
  * Sets VD0 and VD1 bits in IRQ0STATUS to reset the flag, and sets them in
@@ -1048,6 +1102,11 @@
                is_irqhandled = 1;
        }
 
+       if ((irqstatus & CSIA) == CSIA) {
+               isp_csi2_isr();
+               is_irqhandled = 1;
+       }
+
        if (irqstatus & LSC_PRE_ERR) {
                printk(KERN_ERR "isp_sr: LSC_PRE_ERR \n");
                omap_writel(irqstatus, ISP_IRQ0STATUS);
@@ -1083,24 +1142,6 @@
 };
 
 /**
- * isp_set_pipeline - Set bit mask for submodules enabled within the ISP.
- * @soc_type: Sensor to use: 1 - Smart sensor, 0 - Raw sensor.
- *
- * Sets Previewer and Resizer in the bit mask only if its a Raw sensor.
- **/
-void isp_set_pipeline(int soc_type)
-{
-       ispmodule_obj.isp_pipeline |= OMAP_ISP_CCDC;
-
-       if (!soc_type)
-               ispmodule_obj.isp_pipeline |= (OMAP_ISP_PREVIEW |
-                                                       OMAP_ISP_RESIZER);
-
-       return;
-}
-EXPORT_SYMBOL(isp_set_pipeline);
-
-/**
  * omapisp_unset_callback - Unsets all the callbacks associated with ISP module
  **/
 void omapisp_unset_callback()
@@ -2238,6 +2279,13 @@
                        ret_err = PTR_ERR(isp_obj.cam_mclk);
                        goto out_clk_get_mclk;
                }
+               isp_obj.csi2_fck = clk_get(&camera_dev, "csi2_96m_fck");
+               if (IS_ERR(isp_obj.csi2_fck)) {
+                       DPRINTK_ISPCTRL("ISP_ERR: clk_get for csi2_fclk"
+                                                               " failed\n");
+                       ret_err = PTR_ERR(isp_obj.csi2_fck);
+                       goto out_clk_get_csi2_fclk;
+               }
                ret_err = clk_enable(isp_obj.cam_ick);
                if (ret_err) {
                        DPRINTK_ISPCTRL("ISP_ERR: clk_en for ick failed\n");
@@ -2248,6 +2296,12 @@
                        DPRINTK_ISPCTRL("ISP_ERR: clk_en for mclk failed\n");
                        goto out_clk_enable_mclk;
                }
+               ret_err = clk_enable(isp_obj.csi2_fck);
+               if (ret_err) {
+                       DPRINTK_ISPCTRL("ISP_ERR: clk_en for csi2_fclk"
+                                                               " failed\n");
+                       goto out_clk_enable_csi2_fclk;
+               }
                if (off_mode == 1)
                        isp_restore_ctx();
        }
@@ -2258,9 +2312,13 @@
        DPRINTK_ISPCTRL("isp_get: new %d\n", isp_obj.ref_count);
        return isp_obj.ref_count;
 
+out_clk_enable_csi2_fclk:
+       clk_disable(isp_obj.cam_mclk);
 out_clk_enable_mclk:
        clk_disable(isp_obj.cam_ick);
 out_clk_enable_ick:
+       clk_put(isp_obj.csi2_fck);
+out_clk_get_csi2_fclk:
        clk_put(isp_obj.cam_mclk);
 out_clk_get_mclk:
        clk_put(isp_obj.cam_ick);
@@ -2289,8 +2347,10 @@
                        ispmodule_obj.isp_pipeline = 0;
                        clk_disable(isp_obj.cam_ick);
                        clk_disable(isp_obj.cam_mclk);
+                       clk_disable(isp_obj.csi2_fck);
                        clk_put(isp_obj.cam_ick);
                        clk_put(isp_obj.cam_mclk);
+                       clk_put(isp_obj.csi2_fck);
                        memset(&ispcroprect, 0, sizeof(ispcroprect));
                        memset(&cur_rect, 0, sizeof(cur_rect));
 #if ISP_WORKAROUND
Index: omapkernel/drivers/media/video/isp/isp.h
===================================================================
--- omapkernel.orig/drivers/media/video/isp/isp.h       2008-10-15 
20:08:34.000000000 -0500
+++ omapkernel/drivers/media/video/isp/isp.h    2008-10-15 20:08:36.000000000 
-0500
@@ -83,6 +83,8 @@
 };
 
 enum isp_irqevents {
+       CSIA = 0x01,
+       CSIB = 0x10,
        CCDC_VD0 = 0x100,
        CCDC_VD1 = 0x200,
        CCDC_VD2 = 0x400,
@@ -113,6 +115,8 @@
        CBK_LSC_ISR,
        CBK_H3A_AF_DONE,
        CBK_CATCHALL,
+       CBK_CSIA,
+       CBK_CSIB,
        CBK_END,
 };
 
@@ -175,6 +179,9 @@
  * @strobe: Strobe related parameter.
  * @prestrobe: PreStrobe related parameter.
  * @shutter: Shutter related parameter.
+ * @hskip: Horizontal Start Pixel performed in Preview module.
+ * @vskip: Vertical Start Line performed in Preview module.
+ * @wenlog: Store the value for the sensor specific wenlog field.
  */
 struct isp_interface_config {
        enum isp_interface_type ccdc_par_ser;
@@ -185,6 +192,9 @@
        int strobe;
        int prestrobe;
        int shutter;
+       u32 prev_sph;
+       u32 prev_slv;
+       u32 wenlog;
        union {
                struct par {
                        unsigned par_bridge:2;
@@ -308,6 +318,9 @@
 
 void isp_restore_ctx(void);
 
+/* Configure CCDC interface bridge*/
+int isp_configure_interface_bridge(u32 par_bridge);
+
 void isp_print_status(void);
 
 dma_addr_t isp_buf_get(void);
Index: omapkernel/drivers/media/video/isp/ispccdc.c
===================================================================
--- omapkernel.orig/drivers/media/video/isp/ispccdc.c   2008-10-15 
20:08:34.000000000 -0500
+++ omapkernel/drivers/media/video/isp/ispccdc.c        2008-10-15 
20:08:36.000000000 -0500
@@ -82,6 +82,7 @@
        u8 obclamp_en;
        u8 lsc_en;
        struct mutex mutexlock; /* For checking/modifying ccdc_inuse */
+       u32 wenlog;
 } ispccdc_obj;
 
 static struct ispccdc_lsc_config lsc_config;
@@ -316,6 +317,16 @@
 EXPORT_SYMBOL(omap34xx_isp_ccdc_config);
 
 /**
+ * Set the value to be used for CCDC_CFG.WENLOG.
+ *  w - Value of wenlog.
+ */
+void ispccdc_set_wenlog(u32 wenlog)
+{
+       ispccdc_obj.wenlog = wenlog;
+}
+EXPORT_SYMBOL(ispccdc_set_wenlog);
+
+/**
  * ispccdc_request - Reserves the CCDC module.
  *
  * Reserves the CCDC module and assures that is used only once at a time.
@@ -560,17 +571,22 @@
                syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR;
                syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
                syn_mode |= ISPCCDC_SYN_MODE_WEN;
-               syn_mode |= ISPCCDC_SYN_MODE_EXWEN;
-               omap_writel((omap_readl(ISPCCDC_CFG)) | ISPCCDC_CFG_WENLOG,
+               syn_mode &= ~ISPCCDC_SYN_MODE_EXWEN;
+               omap_writel((omap_readl(ISPCCDC_CFG)) & ~ISPCCDC_CFG_WENLOG,
                                                                ISPCCDC_CFG);
+               vpcfg.bitshift_sel = BIT11_2;
+               vpcfg.freq_sel = PIXCLKBY2;
+               ispccdc_config_vp(vpcfg);
+               ispccdc_enable_vp(0);
                break;
 
        case CCDC_OTHERS_VP_MEM:
                syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR;
+               syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
                syn_mode |= ISPCCDC_SYN_MODE_WEN;
                syn_mode |= ISPCCDC_SYN_MODE_EXWEN;
-               omap_writel((omap_readl(ISPCCDC_CFG)) | ISPCCDC_CFG_WENLOG,
-                                                               ISPCCDC_CFG);
+               omap_writel((omap_readl(ISPCCDC_CFG) & ~ISPCCDC_CFG_WENLOG) |
+                                       ispccdc_obj.wenlog, ISPCCDC_CFG);
                vpcfg.bitshift_sel = BIT9_0;
                vpcfg.freq_sel = PIXCLKBY2;
                ispccdc_config_vp(vpcfg);
@@ -1209,16 +1225,24 @@
                                        ISPCCDC_VDINT_1_SHIFT), ISPCCDC_VDINT);
 
        } else if (ispccdc_obj.ccdc_outfmt == CCDC_OTHERS_MEM) {
+               omap_writel(0, ISPCCDC_VP_OUT);
                if (cpu_is_omap3410()) {
                        omap_writel(0 << ISPCCDC_HORZ_INFO_SPH_SHIFT |
                                                ((ispccdc_obj.ccdcout_w - 1) <<
                                                ISPCCDC_HORZ_INFO_NPH_SHIFT),
                                                ISPCCDC_HORZ_INFO);
                } else {
-                       omap_writel(1 << ISPCCDC_HORZ_INFO_SPH_SHIFT |
-                                               ((ispccdc_obj.ccdcout_w - 1) <<
-                                               ISPCCDC_HORZ_INFO_NPH_SHIFT),
+                       if (ispccdc_obj.ccdc_inpfmt == CCDC_RAW) {
+                               omap_writel(1 << ISPCCDC_HORZ_INFO_SPH_SHIFT
+                                               | ((ispccdc_obj.ccdcout_w - 1)
+                                               << ISPCCDC_HORZ_INFO_NPH_SHIFT),
+                                               ISPCCDC_HORZ_INFO);
+                       } else {
+                               omap_writel(0 << ISPCCDC_HORZ_INFO_SPH_SHIFT
+                                               | ((ispccdc_obj.ccdcout_w - 1)
+                                               << ISPCCDC_HORZ_INFO_NPH_SHIFT),
                                                ISPCCDC_HORZ_INFO);
+                       }
                }
                omap_writel(0 << ISPCCDC_VERT_START_SLV0_SHIFT,
                                                        ISPCCDC_VERT_START);
@@ -1227,7 +1251,7 @@
                                                ISPCCDC_VERT_LINES);
 
                ispccdc_config_outlineoffset(ispccdc_obj.ccdcout_w * 2, 0, 0);
-               omap_writel((((ispccdc_obj.ccdcout_h - 1) &
+               omap_writel((((ispccdc_obj.ccdcout_h - 2) &
                                        ISPCCDC_VDINT_0_MASK) <<
                                        ISPCCDC_VDINT_0_SHIFT) |
                                        ((50 & ISPCCDC_VDINT_1_MASK) <<
Index: omapkernel/drivers/media/video/isp/ispccdc.h
===================================================================
--- omapkernel.orig/drivers/media/video/isp/ispccdc.h   2008-10-15 
20:08:34.000000000 -0500
+++ omapkernel/drivers/media/video/isp/ispccdc.h        2008-10-15 
20:08:36.000000000 -0500
@@ -209,4 +209,6 @@
 
 int omap34xx_isp_ccdc_config(void *userspace_add);
 
+void ispccdc_set_wenlog(u32 wenlog);
+
 #endif         /* OMAP_ISP_CCDC_H */
Index: omapkernel/drivers/media/video/isp/isppreview.c
===================================================================
--- omapkernel.orig/drivers/media/video/isp/isppreview.c        2008-10-15 
20:08:34.000000000 -0500
+++ omapkernel/drivers/media/video/isp/isppreview.c     2008-10-15 
20:08:36.000000000 -0500
@@ -184,6 +184,8 @@
        enum preview_color_effect color;
        enum cfa_fmt cfafmt;
        struct mutex ispprev_mutex; /* For checking/modifying prev_inuse */
+       u32 sph;
+       u32 slv;
 } ispprev_obj;
 
 /* Saved parameters */
@@ -759,6 +761,18 @@
 EXPORT_SYMBOL(isppreview_config_datapath);
 
 /**
+ * isppreview_set_skip - Set the number of rows/columns that should be skipped.
+ *  h - Start Pixel Horizontal.
+ *  v - Start Line Vertical.
+ **/
+void isppreview_set_skip(u32 h, u32 v)
+{
+       ispprev_obj.sph = h;
+       ispprev_obj.slv = v;
+}
+EXPORT_SYMBOL(isppreview_set_skip);
+
+/**
  * isppreview_config_ycpos - Configure byte layout of YUV image.
  * @mode: Indicates the required byte layout.
  **/
@@ -1487,7 +1501,12 @@
        if ((ispprev_obj.yenh_en) || (ispprev_obj.csup_en))
                prevout_w -= 2;
 
-       prevout_w -= 4;
+       /* Start at the correct row/column by skipping
+        * a Sensor specific amount.
+        */
+       prevout_w -= ispprev_obj.sph;
+       prevout_h -= ispprev_obj.slv;
+
 
        if (prevout_w % 2)
                prevout_w -= 1;
@@ -1530,10 +1549,10 @@
                return -EINVAL;
        }
 
-       omap_writel((4 << ISPPRV_HORZ_INFO_SPH_SHIFT) |
+       omap_writel((ispprev_obj.sph << ISPPRV_HORZ_INFO_SPH_SHIFT) |
                                                (ispprev_obj.previn_w - 1),
                                                ISPPRV_HORZ_INFO);
-       omap_writel((0 << ISPPRV_VERT_INFO_SLV_SHIFT) |
+       omap_writel((ispprev_obj.slv << ISPPRV_VERT_INFO_SLV_SHIFT) |
                                                (ispprev_obj.previn_h - 1),
                                                ISPPRV_VERT_INFO);
 
@@ -1817,6 +1836,8 @@
        }
 
        /* Init values */
+       ispprev_obj.sph = 2;
+       ispprev_obj.slv = 0;
        ispprev_obj.color = PREV_DEFAULT_COLOR;
        ispprev_obj.contrast = ISPPRV_CONTRAST_DEF;
        params->contrast = ISPPRV_CONTRAST_DEF;
Index: omapkernel/drivers/media/video/isp/isppreview.h
===================================================================
--- omapkernel.orig/drivers/media/video/isp/isppreview.h        2008-10-15 
20:08:34.000000000 -0500
+++ omapkernel/drivers/media/video/isp/isppreview.h     2008-10-15 
20:08:36.000000000 -0500
@@ -353,4 +353,6 @@
 
 int omap34xx_isp_tables_update(struct isptables_update *isptables_struct);
 
+void isppreview_set_skip(u32 h, u32 v);
+
 #endif/* OMAP_ISP_PREVIEW_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to