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