[PATCH 24/28] [OMAPZOOM] OMAP: CAM: Add CSI2 changes to ISP driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Sergio Aguirre <saaguirre@xxxxxx>

OMAP: CAM: Add CSI2 changes to ISP driver

This adds CSI2 related changes to the ISP driver.

Signed-off-by: Sergio Aguirre <saaguirre@xxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux