marvell-ccic: update ccic driver to support some features
v3 cover marvell-ccic: update ccic driver to support some features
The patch set adds some feature into the marvell ccic driver
Patch 1: Support MIPI sensor
Patch 2: Support clock tree
Patch 3: reset ccic when stop streaming, which makes CCIC more stable Patch 4: refine the mcam_set_contig_buffer function
Patch 5: add some new fmts to support
Patch 6: add SOF-EOF pair check to make the CCIC more stable Patch 7: use resource managed allocation
change log:
Patch 1:
fix the unlock issue
add some comments
remove int mipi_enabled in struct mmp_camera_platform_data get "mipi" clk at first in mmpcam_power_up()
Patch 2:
Add mcam_deinit_clk function
Some changes in mcam_init_clk function
Patch 7:
A little adjustment based patch 2 change
Libin Yang (7):
marvell-ccic: add MIPI support for marvell-ccic driver
marvell-ccic: add clock tree support for marvell-ccic driver
marvell-ccic: reset ccic phy when stop streaming for stability
marvell-ccic: refine mcam_set_contig_buffer function
marvell-ccic: add new formats support for marvell-ccic driver
marvell-ccic: add SOF / EOF pair check for marvell-ccic driver
marvell-ccic: switch to resource managed allocation and request
drivers/media/platform/marvell-ccic/cafe-driver.c | 4 +- drivers/media/platform/marvell-ccic/mcam-core.c | 325 +++++++++++++++++---- drivers/media/platform/marvell-ccic/mcam-core.h | 50 +++- drivers/media/platform/marvell-ccic/mmp-driver.c | 274 ++++++++++++++--- include/media/mmp-camera.h | 18 ++ 5 files changed, 578 insertions(+), 93 deletions(-)
Signature · 1 line
1.7.9.5
PATCH v3 1/7 marvell-ccic: add MIPI support for marvell-ccic driver
This patch adds the MIPI support for marvell-ccic. Board driver should determine whether using MIPI or not.
--- drivers/media/platform/marvell-ccic/cafe-driver.c | 4 +- drivers/media/platform/marvell-ccic/mcam-core.c | 80 +++++++++++- drivers/media/platform/marvell-ccic/mcam-core.h | 37 +++++- drivers/media/platform/marvell-ccic/mmp-driver.c | 136 ++++++++++++++++++++- include/media/mmp-camera.h | 18 +++ 5 files changed, 262 insertions(+), 13 deletions(-)
drivers/media/platform/marvell-ccic/cafe-driver.c +3 -1
@@ -400,7 +400,7 @@ static void cafe_ctlr_init(struct mcam_camera *mcam) } -static void cafe_ctlr_power_up (struct mcam_camera *mcam) +static int cafe_ctlr_power_up (struct mcam_camera *mcam) {/* * Part one of the sensor dance: turn the global
@@ -415,6 +415,8 @@ static void cafe_ctlr_power_up(struct mcam_camera *mcam)*/ mcam_reg_write (mcam,REG_GPR ,GPR_C1EN |GPR_C0EN );/* pwr up, reset */ mcam_reg_write (mcam,REG_GPR ,GPR_C1EN |GPR_C0EN |GPR_C0 ); + +return 0 ; }static void cafe_ctlr_power_down (struct mcam_camera *mcam)
drivers/media/platform/marvell-ccic/mcam-core.c +76 -4
139 lines not on this page · raw message
drivers/media/platform/marvell-ccic/mcam-core.h +34 -3
@@ -102,11 +102,28 @@ struct mcam_camera {short int clock_speed;/* Sensor clock speed, default 30 */ short int use_smbus;/* SMBUS or straight I2c? */ enum mcam_buffer_mode buffer_mode; + +int mclk_min;/* The minimal value of mclk */ +int mclk_src;/* which clock source the mclk derives from */ +int mclk_div;/* Clock Divider Value for MCLK */ + +enum v4l2_mbus_type bus_type; +/* MIPI support */ +/* The dphy config value, allocated in board file +* dphy[0]: DPHY3 +* dphy[1]: DPHY5 +* dphy[2]: DPHY6 +*/ +int *dphy; +bool mipi_enabled;/* flag whether mipi is enabled already */ +int lane;/* lane number */ +/* * Callbacks from the core to the platform code. */ -void (*plat_power_up) (struct mcam_camera *cam); +int (*plat_power_up) (struct mcam_camera *cam);void (*plat_power_down) (struct mcam_camera *cam); +void (*calc_dphy) (struct mcam_camera *cam);/* * Everything below here is private to the mcam core and
@@ -220,6 +237,17 @@ int mccic_resume(struct mcam_camera *cam);#define REG_Y0BAR 0x00#define REG_Y1BAR 0x04#define REG_Y2BAR 0x08 + +/* +* register definitions for MIPI support +*/ +#define REG_CSI2_CTRL0 0x100 +#define CSI2_C0_MIPI_EN (0x1 << 0) +#define CSI2_C0_ACT_LANE (n) ((n-1) << 1) +#define REG_CSI2_DPHY3 0x12c +#define REG_CSI2_DPHY5 0x134 +#define REG_CSI2_DPHY6 0x138 +/* ... */ #define REG_IMGPITCH 0x24/* Image pitch register */
@@ -288,13 +316,16 @@ int mccic_resume(struct mcam_camera *cam);#define C0_YUVE_XUVY 0x00020000/* 420: .UVY */ #define C0_YUVE_XVUY 0x00030000/* 420: .VUY */ /* Bayer bits 18,19 if needed */ +#define C0_EOF_VSYNC 0x00400000/* Generate EOF by VSYNC */ +#define C0_VEDGE_CTRL 0x00800000/* Detect falling edge of VSYNC */ #define C0_HPOL_LOW 0x01000000/* HSYNC polarity active low */ #define C0_VPOL_LOW 0x02000000/* VSYNC polarity active low */ #define C0_VCLK_LOW 0x04000000/* VCLK on falling edge */ #define C0_DOWNSCALE 0x08000000/* Enable downscaler */ -#define C0_SIFM_MASK 0xc0000000/* SIF mode bits */ +/* SIFMODE */ #define C0_SIF_HVSYNC 0x00000000/* Use H/VSYNC */ -#define CO_SOF_NOSYNC 0x40000000/* Use inband active signaling */ +#define C0_SOF_NOSYNC 0x40000000/* Use inband active signaling */ +#define C0_SIFM_MASK 0xc0000000/* SIF mode bits */ /* Bits below C1_444ALPHA are not present in Cafe */ #define REG_CTRL1 0x40/* Control 1 */
drivers/media/platform/marvell-ccic/mmp-driver.c +131 -5
209 lines not on this page · raw message
include/media/mmp-camera.h +18 -0
@@ -1,9 +1,27 @@ +#include <media/v4l2-mediabus.h> /* * Information for the Marvell Armada MMP camera */ +enum dphy3_algo { +DPHY3_ALGO_DEFAULT =0 , +DPHY3_ALGO_PXA910 , +DPHY3_ALGO_PXA2128 +}; +struct mmp_camera_platform_data {struct platform_device *i2c_device;int sensor_power_gpio;int sensor_reset_gpio; +enum v4l2_mbus_type bus_type; +int mclk_min;/* The minimal value of MCLK */ +int mclk_src;/* which clock source the MCLK derives from */ +int mclk_div;/* Clock Divider Value for MCLK */ +/* +* MIPI support +*/ +int dphy[3 ];/* DPHY: CSI2_DPHY3, CSI2_DPHY5, CSI2_DPHY6 */ +enum dphy3_algo dphy3_algo;/* algos for calculate CSI2_DPHY3 */ +int lane;/* ccic used lane number; 0 means DVP mode */ +int lane_clk; };
Signature · 1 line
1.7.9.5
Re: [PATCH v3 1/7] marvell-ccic: add MIPI support for marvell-ccic driver
Quoted 2 lines · On Wed, 3 Jul 2013 13:55:58 +0800 Libin Yang <[email protected]> wrote:
This patch adds the MIPI support for marvell-ccic. Board driver should determine whether using MIPI or not.
Sorry for taking so long...I wanted to be able to carve out some time and look at things closely. At this point, there's nothing that, I think, needs to further hold up the merging of this code. So you can add:
to the entire series. Thanks again for doing this work, and for your patience with my many comments!
jon
PATCH v3 2/7 marvell-ccic: add clock tree support for marvell-ccic driver
In reply to Libin YangThis patch adds the clock tree support for marvell-ccic.
--- drivers/media/platform/marvell-ccic/mcam-core.h | 5 ++ drivers/media/platform/marvell-ccic/mmp-driver.c | 61 ++++++++++++++++++++++ 2 files changed, 66 insertions(+)
drivers/media/platform/marvell-ccic/mcam-core.h +5 -0
@@ -83,6 +83,8 @@ struct mcam_frame_state {unsigned int delivered; }; +#define NR_MCAM_CLK 3 +/* * A description of one of our devices. * Locking: controlled by s_mutex. Certain fields, however, require
@@ -118,6 +120,9 @@ struct mcam_camera {bool mipi_enabled;/* flag whether mipi is enabled already */ int lane;/* lane number */ +/* clock tree support */ +struct clk *clk[NR_MCAM_CLK ]; +/* * Callbacks from the core to the platform code. */
drivers/media/platform/marvell-ccic/mmp-driver.c +61 -0
109 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH v3 3/7 marvell-ccic: reset ccic phy when stop streaming for stability
In reply to Libin YangThis patch adds the reset ccic phy operation when stop streaming.
Stop streaming without reset ccic phy, the next start streaming may be unstable.
Also need add CCIC2 definition when PXA688/PXA2128 support dual ccics.
--- drivers/media/platform/marvell-ccic/mcam-core.c | 6 ++++++ drivers/media/platform/marvell-ccic/mcam-core.h | 2 ++ drivers/media/platform/marvell-ccic/mmp-driver.c | 25 ++++++++++++++++++++++ 3 files changed, 33 insertions(+)
drivers/media/platform/marvell-ccic/mcam-core.c +6 -0
@@ -1059,6 +1059,12 @@ static int mcam_vb_stop_streaming(struct vb2_queue *vq)return -EINVAL ;mcam_ctlr_stop_dma (cam);/* +* Reset the CCIC PHY after stopping streaming, +* otherwise, the CCIC may be unstable. +*/ +if (cam->ctlr_reset) + cam->ctlr_reset (cam); +/* * VB2 reclaims the buffers, so we need to forget * about them. */
drivers/media/platform/marvell-ccic/mcam-core.h +2 -0
@@ -109,6 +109,7 @@ struct mcam_camera {int mclk_src;/* which clock source the mclk derives from */ int mclk_div;/* Clock Divider Value for MCLK */ +int ccic_id;enum v4l2_mbus_type bus_type;/* MIPI support */ /* The dphy config value, allocated in board file
@@ -129,6 +130,7 @@ struct mcam_camera {int (*plat_power_up) (struct mcam_camera *cam);void (*plat_power_down) (struct mcam_camera *cam);void (*calc_dphy) (struct mcam_camera *cam); +void (*ctlr_reset) (struct mcam_camera *cam);/* * Everything below here is private to the mcam core and
drivers/media/platform/marvell-ccic/mmp-driver.c +25 -0
@@ -106,6 +106,7 @@ static struct mmp_camera *mmpcam_find_device(struct platform_device *pdev)#define CPU_SUBSYS_PMU_BASE 0xd4282800#define REG_CCIC_DCGCR 0x28/* CCIC dyn clock gate ctrl reg */ #define REG_CCIC_CRCR 0x50/* CCIC clk reset ctrl reg */ +#define REG_CCIC2_CRCR 0xf4/* CCIC2 clk reset ctrl reg */ static void mcam_clk_enable (struct mcam_camera *mcam) {
@@ -195,6 +196,28 @@ static void mmpcam_power_down(struct mcam_camera *mcam)mcam_clk_disable (mcam); } +void mcam_ctlr_reset (struct mcam_camera *mcam) +{ +unsigned long val; +struct mmp_camera *cam =mcam_to_cam (mcam); + +if (mcam->ccic_id) { +/* +* Using CCIC2 +*/ + val =ioread32 (cam->power_regs +REG_CCIC2_CRCR ); +iowrite32 (val & ~0x2 , cam->power_regs +REG_CCIC2_CRCR ); +iowrite32 (val |0x2 , cam->power_regs +REG_CCIC2_CRCR ); + }else { +/* +* Using CCIC1 +*/ + val =ioread32 (cam->power_regs +REG_CCIC_CRCR ); +iowrite32 (val & ~0x2 , cam->power_regs +REG_CCIC_CRCR ); +iowrite32 (val |0x2 , cam->power_regs +REG_CCIC_CRCR ); + } +} +/* * calc the dphy register values * There are three dphy registers being used.
@@ -355,9 +378,11 @@ static int mmpcam_probe(struct platform_device *pdev) mcam = &cam->mcam; mcam->plat_power_up = mmpcam_power_up; mcam->plat_power_down = mmpcam_power_down; + mcam->ctlr_reset = mcam_ctlr_reset; mcam->calc_dphy = mmpcam_calc_dphy; mcam->dev = &pdev->dev; mcam->use_smbus =0 ; + mcam->ccic_id = pdev->id; mcam->mclk_min = pdata->mclk_min; mcam->mclk_src = pdata->mclk_src; mcam->mclk_div = pdata->mclk_div;
Signature · 1 line
1.7.9.5
PATCH v3 4/7 marvell-ccic: refine mcam_set_contig_buffer function
In reply to Libin YangThis patch refines mcam_set_contig_buffer() in mcam core. It can remove redundant code line and enhance readability.
--- drivers/media/platform/marvell-ccic/mcam-core.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-)
drivers/media/platform/marvell-ccic/mcam-core.c +10 -11
@@ -482,22 +482,21 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame)*/ if (list_empty (&cam->buffers)) { buf = cam->vb_bufs[frame ^0x1 ]; - cam->vb_bufs[frame] = buf; -mcam_reg_write (cam, frame ==0 ?REG_Y0BAR :REG_Y1BAR , -vb2_dma_contig_plane_dma_addr (&buf->vb_buf,0 ));set_bit (CF_SINGLE_BUFFER , &cam->flags); cam->frame_state.singles++; -return ; + }else { +/* +* OK, we have a buffer we can use. +*/ + buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, + queue); +list_del_init (&buf->queue); +clear_bit (CF_SINGLE_BUFFER , &cam->flags); } -/* -* OK, we have a buffer we can use. -*/ - buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue); -list_del_init (&buf->queue); + + cam->vb_bufs[frame] = buf;mcam_reg_write (cam, frame ==0 ?REG_Y0BAR :REG_Y1BAR ,vb2_dma_contig_plane_dma_addr (&buf->vb_buf,0 )); - cam->vb_bufs[frame] = buf; -clear_bit (CF_SINGLE_BUFFER , &cam->flags); }/*
Signature · 1 line
1.7.9.5
PATCH v3 5/7 marvell-ccic: add new formats support for marvell-ccic driver
In reply to Libin YangThis patch adds some planar formats support for marvell-ccic.
--- drivers/media/platform/marvell-ccic/mcam-core.c | 192 +++++++++++++++++++---- drivers/media/platform/marvell-ccic/mcam-core.h | 6 + 2 files changed, 165 insertions(+), 33 deletions(-)
drivers/media/platform/marvell-ccic/mcam-core.c +159 -33
@@ -103,6 +103,7 @@ static struct mcam_format_struct {__u8 *desc;__u32 pixelformat;int bpp;/* Bytes per pixel */ +bool planar;enum v4l2_mbus_pixelcode mbus_code; } mcam_formats[] = { {
@@ -110,24 +111,56 @@ static struct mcam_format_struct { .pixelformat = V4L2_PIX_FMT_YUYV, .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, .bpp = 2, + .planar = false, + }, + { + .desc = "UYVY 4:2:2", + .pixelformat = V4L2_PIX_FMT_UYVY, + .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .bpp = 2, + .planar = false, + }, + { + .desc = "YUV 4:2:2 PLANAR", + .pixelformat = V4L2_PIX_FMT_YUV422P, + .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .bpp = 2, + .planar = true, + }, + { + .desc = "YUV 4:2:0 PLANAR", + .pixelformat = V4L2_PIX_FMT_YUV420, + .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .bpp = 2, + .planar = true, + }, + { + .desc = "YVU 4:2:0 PLANAR", + .pixelformat = V4L2_PIX_FMT_YVU420, + .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, + .bpp = 2, + .planar = true, }, { .desc = "RGB 444", .pixelformat = V4L2_PIX_FMT_RGB444, .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 2, + .planar = false, }, { .desc = "RGB 565", .pixelformat = V4L2_PIX_FMT_RGB565, .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, .bpp = 2, + .planar = false, }, { .desc = "Raw RGB Bayer", .pixelformat = V4L2_PIX_FMT_SBGGR8, .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8, - .bpp = 1 + .bpp = 1, + .planar = false, }, }; #define N_MCAM_FMTS ARRAY_SIZE(mcam_formats)
@@ -170,6 +203,12 @@ struct mcam_dma_desc {u32 segment_len; }; +struct yuv_pointer_t { +dma_addr_t y; +dma_addr_t u; +dma_addr_t v; +}; +/* * Our buffer type for working with videobuf2. Note that the vb2 * developers have decreed that struct vb2_buffer must be at the
@@ -181,6 +220,7 @@ struct mcam_vb_buffer {struct mcam_dma_desc *dma_desc;/* Descriptor virtual address */ dma_addr_t dma_desc_pa;/* Descriptor physical address */ int dma_desc_nent;/* Number of mapped descriptors */ +struct yuv_pointer_t yuv_p; };static inline struct mcam_vb_buffer *vb_to_mvb (struct vb2_buffer *vb)
@@ -466,6 +506,15 @@ static inline int mcam_check_dma_buffers(struct mcam_camera *cam)/* * DMA-contiguous code. */ + +static bool mcam_fmt_is_planar (__u32 pfmt) +{ +struct mcam_format_struct *f; + + f =mcam_find_format (pfmt); +return f->planar; +} +/* * Set up a contiguous buffer for the given frame. Here also is where * the underrun strategy is set: if there is no buffer available, reuse
@@ -477,6 +526,11 @@ static inline int mcam_check_dma_buffers(struct mcam_camera *cam)static void mcam_set_contig_buffer (struct mcam_camera *cam,int frame) {struct mcam_vb_buffer *buf; +struct v4l2_pix_format *fmt = &cam->pix_format; +dma_addr_t dma_handle; +u32 pixel_count = fmt->width * fmt->height; +struct vb2_buffer *vb; +/* * If there are no available buffers, go into single mode */
@@ -495,8 +549,35 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame) } cam->vb_bufs[frame] = buf; -mcam_reg_write (cam, frame ==0 ?REG_Y0BAR :REG_Y1BAR , -vb2_dma_contig_plane_dma_addr (&buf->vb_buf,0 )); + vb = &buf->vb_buf; + + dma_handle =vb2_dma_contig_plane_dma_addr (vb,0 ); + buf->yuv_p.y = dma_handle; + +switch (cam->pix_format.pixelformat) { +case V4L2_PIX_FMT_YUV422P : + buf->yuv_p.u = buf->yuv_p.y + pixel_count; + buf->yuv_p.v = buf->yuv_p.u + pixel_count /2 ; +break ; +case V4L2_PIX_FMT_YUV420 : + buf->yuv_p.u = buf->yuv_p.y + pixel_count; + buf->yuv_p.v = buf->yuv_p.u + pixel_count /4 ; +break ; +case V4L2_PIX_FMT_YVU420 : + buf->yuv_p.v = buf->yuv_p.y + pixel_count; + buf->yuv_p.u = buf->yuv_p.v + pixel_count /4 ; +break ; +default : +break ; + } + +mcam_reg_write (cam, frame ==0 ?REG_Y0BAR :REG_Y1BAR , buf->yuv_p.y); +if (mcam_fmt_is_planar (fmt->pixelformat)) { +mcam_reg_write (cam, frame ==0 ? +REG_U0BAR :REG_U1BAR , buf->yuv_p.u); +mcam_reg_write (cam, frame ==0 ? +REG_V0BAR :REG_V1BAR , buf->yuv_p.v); + } }/*
@@ -654,49 +735,84 @@ static inline void mcam_sg_restart(struct mcam_camera *cam)*/ static void mcam_ctlr_image (struct mcam_camera *cam) { -int imgsz;struct v4l2_pix_format *fmt = &cam->pix_format; +u32 widthy =0 , widthuv =0 , imgsz_h, imgsz_w; + +cam_dbg (cam,"camera: bytesperline = %d; height = %d\n" , + fmt->bytesperline, fmt->sizeimage / fmt->bytesperline); + imgsz_h = (fmt->height <<IMGSZ_V_SHIFT ) &IMGSZ_V_MASK ; + imgsz_w = (fmt->width *2 ) &IMGSZ_H_MASK ; + +switch (fmt->pixelformat) { +case V4L2_PIX_FMT_YUYV : +case V4L2_PIX_FMT_UYVY : + widthy = fmt->width *2 ; + widthuv =0 ; +break ; +case V4L2_PIX_FMT_JPEG : + imgsz_h = (fmt->sizeimage / fmt->bytesperline) <<IMGSZ_V_SHIFT ; + widthy = fmt->bytesperline; + widthuv =0 ; +break ; +case V4L2_PIX_FMT_YUV422P : +case V4L2_PIX_FMT_YUV420 : +case V4L2_PIX_FMT_YVU420 : + widthy = fmt->width; + widthuv = fmt->width /2 ; +break ; +default : + widthy = fmt->bytesperline; + widthuv =0 ; + } + +mcam_reg_write_mask (cam,REG_IMGPITCH , widthuv <<16 | widthy, +IMGP_YP_MASK |IMGP_UVP_MASK ); +mcam_reg_write (cam,REG_IMGSIZE , imgsz_h | imgsz_w); +mcam_reg_write (cam,REG_IMGOFFSET ,0x0 ); - imgsz = ((fmt->height <<IMGSZ_V_SHIFT ) &IMGSZ_V_MASK ) | - (fmt->bytesperline &IMGSZ_H_MASK ); -mcam_reg_write (cam,REG_IMGSIZE , imgsz); -mcam_reg_write (cam,REG_IMGOFFSET ,0 ); -/* YPITCH just drops the last two bits */ -mcam_reg_write_mask (cam,REG_IMGPITCH , fmt->bytesperline, -IMGP_YP_MASK );/* * Tell the controller about the image format we are using. */ -switch (cam->pix_format.pixelformat) { +switch (fmt->pixelformat) { +case V4L2_PIX_FMT_YUV422P : +mcam_reg_write_mask (cam,REG_CTRL0 , +C0_DF_YUV |C0_YUV_PLANAR |C0_YUVE_YVYU ,C0_DF_MASK ); +break ; +case V4L2_PIX_FMT_YUV420 : +case V4L2_PIX_FMT_YVU420 : +mcam_reg_write_mask (cam,REG_CTRL0 , +C0_DF_YUV |C0_YUV_420PL |C0_YUVE_YVYU ,C0_DF_MASK ); +break ;case V4L2_PIX_FMT_YUYV : -mcam_reg_write_mask (cam,REG_CTRL0 , -C0_DF_YUV |C0_YUV_PACKED |C0_YUVE_YUYV , -C0_DF_MASK ); -break ; - +mcam_reg_write_mask (cam,REG_CTRL0 , +C0_DF_YUV |C0_YUV_PACKED |C0_YUVE_UYVY ,C0_DF_MASK ); +break ; +case V4L2_PIX_FMT_UYVY : +mcam_reg_write_mask (cam,REG_CTRL0 , +C0_DF_YUV |C0_YUV_PACKED |C0_YUVE_YUYV ,C0_DF_MASK ); +break ; +case V4L2_PIX_FMT_JPEG : +mcam_reg_write_mask (cam,REG_CTRL0 , +C0_DF_YUV |C0_YUV_PACKED |C0_YUVE_YUYV ,C0_DF_MASK ); +break ;case V4L2_PIX_FMT_RGB444 : -mcam_reg_write_mask (cam,REG_CTRL0 , -C0_DF_RGB |C0_RGBF_444 |C0_RGB4_XRGB , -C0_DF_MASK ); +mcam_reg_write_mask (cam,REG_CTRL0 , +C0_DF_RGB |C0_RGBF_444 |C0_RGB4_XRGB ,C0_DF_MASK );/* Alpha value? */ -break ; - +break ;case V4L2_PIX_FMT_RGB565 : -mcam_reg_write_mask (cam,REG_CTRL0 , -C0_DF_RGB |C0_RGBF_565 |C0_RGB5_BGGR , -C0_DF_MASK ); -break ; - +mcam_reg_write_mask (cam,REG_CTRL0 , +C0_DF_RGB |C0_RGBF_565 |C0_RGB5_BGGR ,C0_DF_MASK ); +break ;default : -cam_err (cam,"Unknown format %x\n" , cam->pix_format.pixelformat); -break ; +cam_err (cam,"camera: unknown format: %#x\n" , fmt->pixelformat); +break ; } +/* * Make sure it knows we want to use hsync/vsync. */ -mcam_reg_write_mask (cam,REG_CTRL0 ,C0_SIF_HVSYNC , -C0_SIFM_MASK ); - +mcam_reg_write_mask (cam,REG_CTRL0 ,C0_SIF_HVSYNC ,C0_SIFM_MASK );/* * This field controls the generation of EOF(DVP only) */
@@ -1174,6 +1290,7 @@ static int mcam_setup_vb2(struct mcam_camera *cam)#ifdef MCAM_MODE_DMA_CONTIG vq->ops = &mcam_vb2_ops; vq->mem_ops = &vb2_dma_contig_memops; + vq->buf_struct_size =sizeof (struct mcam_vb_buffer ); cam->vb_alloc_ctx =vb2_dma_contig_init_ctx (cam->dev); vq->io_modes =VB2_MMAP |VB2_USERPTR ; cam->dma_setup = mcam_ctlr_dma_contig;
@@ -1184,6 +1301,7 @@ static int mcam_setup_vb2(struct mcam_camera *cam)#ifdef MCAM_MODE_DMA_SG vq->ops = &mcam_vb2_sg_ops; vq->mem_ops = &vb2_dma_sg_memops; + vq->buf_struct_size =sizeof (struct mcam_vb_buffer ); vq->io_modes =VB2_MMAP |VB2_USERPTR ; cam->dma_setup = mcam_ctlr_dma_sg; cam->frame_complete = mcam_dma_sg_done;
@@ -1334,7 +1452,15 @@ static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, ret =sensor_call (cam, video, try_mbus_fmt, &mbus_fmt);mutex_unlock (&cam->s_mutex);v4l2_fill_pix_format (pix, &mbus_fmt); - pix->bytesperline = pix->width * f->bpp; +switch (f->pixelformat) { +case V4L2_PIX_FMT_YUV420 : +case V4L2_PIX_FMT_YVU420 : + pix->bytesperline = pix->width *3 /2 ; +break ; +default : + pix->bytesperline = pix->width * f->bpp; +break ; + } pix->sizeimage = pix->height * pix->bytesperline;return ret; }
drivers/media/platform/marvell-ccic/mcam-core.h +6 -0
@@ -244,6 +244,12 @@ int mccic_resume(struct mcam_camera *cam);#define REG_Y0BAR 0x00#define REG_Y1BAR 0x04#define REG_Y2BAR 0x08 +#define REG_U0BAR 0x0c +#define REG_U1BAR 0x10 +#define REG_U2BAR 0x14 +#define REG_V0BAR 0x18 +#define REG_V1BAR 0x1C +#define REG_V2BAR 0x20/* * register definitions for MIPI support
Signature · 1 line
1.7.9.5
PATCH v3 6/7 marvell-ccic: add SOF / EOF pair check for marvell-ccic driver
In reply to Libin YangThis patch adds the SOFx/EOFx pair check for marvell-ccic.
When switching format, the last EOF may not arrive when stop streamning. And the EOF will be detected in the next start streaming.
Must ensure clear the left over frame flags before every really start streaming.
--- drivers/media/platform/marvell-ccic/mcam-core.c | 30 ++++++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-)
drivers/media/platform/marvell-ccic/mcam-core.c +26 -4
@@ -95,6 +95,9 @@ MODULE_PARM_DESC(buffer_mode,#define CF_CONFIG_NEEDED 4/* Must configure hardware */ #define CF_SINGLE_BUFFER 5/* Running with a single buffer */ #define CF_SG_RESTART 6/* SG restart needed */ +#define CF_FRAME_SOF0 7/* Frame 0 started */ +#define CF_FRAME_SOF1 8 +#define CF_FRAME_SOF2 9 #define sensor_call(cam, o, f, args...) \ v4l2_subdev_call(cam->sensor, o, f, ##args)
@@ -261,8 +264,10 @@ static void mcam_reset_buffers(struct mcam_camera *cam)int i; cam->next_buf =-1 ; -for (i =0 ; i < cam->nbufs; i++) +for (i =0 ; i < cam->nbufs; i++) {clear_bit (i, &cam->flags); +clear_bit (CF_FRAME_SOF0 + i, &cam->flags); + } }static inline int mcam_needs_config (struct mcam_camera *cam)
@@ -1140,6 +1145,7 @@ static void mcam_vb_wait_finish(struct vb2_queue *vq)static int mcam_vb_start_streaming (struct vb2_queue *vq,unsigned int count) {struct mcam_camera *cam =vb2_get_drv_priv (vq); +unsigned int frame;if (cam->state !=S_IDLE ) {INIT_LIST_HEAD (&cam->buffers);
@@ -1157,6 +1163,14 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) cam->state =S_BUFWAIT ;return 0 ; } + +/* +* Ensure clear the left over frame flags +* before every really start streaming +*/ +for (frame =0 ; frame < cam->nbufs; frame++) +clear_bit (CF_FRAME_SOF0 + frame, &cam->flags); +return mcam_read_setup (cam); }
@@ -1845,9 +1859,11 @@ int mccic_irq(struct mcam_camera *cam, unsigned int irqs)* each time. */ for (frame =0 ; frame < cam->nbufs; frame++) -if (irqs & (IRQ_EOF0 << frame)) { +if (irqs & (IRQ_EOF0 << frame) && +test_bit (CF_FRAME_SOF0 + frame, &cam->flags)) {mcam_frame_complete (cam, frame); handled =1 ; +clear_bit (CF_FRAME_SOF0 + frame, &cam->flags);if (cam->buffer_mode == B_DMA_sg)break ; }
@@ -1856,9 +1872,15 @@ int mccic_irq(struct mcam_camera *cam, unsigned int irqs)* code assumes that we won't get multiple frame interrupts * at once; may want to rethink that. */ -if (irqs & (IRQ_SOF0 |IRQ_SOF1 |IRQ_SOF2 )) { +for (frame =0 ; frame < cam->nbufs; frame++) { +if (irqs & (IRQ_SOF0 << frame)) { +set_bit (CF_FRAME_SOF0 + frame, &cam->flags); + handled =IRQ_HANDLED ; + } + } + +if (handled ==IRQ_HANDLED ) {set_bit (CF_DMA_ACTIVE , &cam->flags); - handled =1 ;if (cam->buffer_mode == B_DMA_sg)mcam_ctlr_stop (cam); }
Signature · 1 line
1.7.9.5
PATCH v3 7/7 marvell-ccic: switch to resource managed allocation and request
In reply to Libin YangThis patch switchs to resource managed allocation and request in mmp-driver. It can remove free resource operations.
--- drivers/media/platform/marvell-ccic/mmp-driver.c | 60 ++++++++-------------- 1 file changed, 22 insertions(+), 38 deletions(-)
drivers/media/platform/marvell-ccic/mmp-driver.c +22 -38
@@ -368,7 +368,7 @@ static int mmpcam_probe(struct platform_device *pdev)if (!pdata)return -ENODEV ; - cam =kzalloc (sizeof (*cam),GFP_KERNEL ); + cam =devm_kzalloc (&pdev->dev,sizeof (*cam),GFP_KERNEL );if (cam ==NULL )return -ENOMEM ; cam->pdev = pdev;
@@ -399,15 +399,11 @@ static int mmpcam_probe(struct platform_device *pdev) res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );if (res ==NULL ) {dev_err (&pdev->dev,"no iomem resource!\n" ); - ret = -ENODEV ; - goto out_free; - } - mcam->regs =ioremap (res->start,resource_size (res)); -if (mcam->regs ==NULL ) { -dev_err (&pdev->dev,"MMIO ioremap fail\n" ); - ret = -ENODEV ; - goto out_free; +return -ENODEV ; } + mcam->regs =devm_ioremap_resource (&pdev->dev, res); +if (IS_ERR (mcam->regs)) +return PTR_ERR (mcam->regs);/* * Power/clock memory is elsewhere; get it too. Perhaps this * should really be managed outside of this driver?
@@ -415,40 +411,37 @@ static int mmpcam_probe(struct platform_device *pdev) res =platform_get_resource (pdev,IORESOURCE_MEM ,1 );if (res ==NULL ) {dev_err (&pdev->dev,"no power resource!\n" ); - ret = -ENODEV ; - goto out_unmap1; - } - cam->power_regs =ioremap (res->start,resource_size (res)); -if (cam->power_regs ==NULL ) { -dev_err (&pdev->dev,"power MMIO ioremap fail\n" ); - ret = -ENODEV ; - goto out_unmap1; +return -ENODEV ; } + cam->power_regs =devm_ioremap_resource (&pdev->dev, res); +if (IS_ERR (cam->power_regs)) +return PTR_ERR (cam->power_regs);/* * Find the i2c adapter. This assumes, of course, that the * i2c bus is already up and functioning. */ mcam->i2c_adapter =platform_get_drvdata (pdata->i2c_device);if (mcam->i2c_adapter ==NULL ) { - ret = -ENODEV ;dev_err (&pdev->dev,"No i2c adapter\n" ); - goto out_unmap2; +return -ENODEV ; }/* * Sensor GPIO pins. */ - ret =gpio_request (pdata->sensor_power_gpio,"cam-power" ); + ret =devm_gpio_request (&pdev->dev, pdata->sensor_power_gpio, +"cam-power" );if (ret) {dev_err (&pdev->dev,"Can't get sensor power gpio %d" , pdata->sensor_power_gpio); - goto out_unmap2; +return ret; }gpio_direction_output (pdata->sensor_power_gpio,0 ); - ret =gpio_request (pdata->sensor_reset_gpio,"cam-reset" ); + ret =devm_gpio_request (&pdev->dev, pdata->sensor_reset_gpio, +"cam-reset" );if (ret) {dev_err (&pdev->dev,"Can't get sensor reset gpio %d" , pdata->sensor_reset_gpio); - goto out_gpio; +return ret; }gpio_direction_output (pdata->sensor_reset_gpio,0 );
@@ -459,10 +452,10 @@ static int mmpcam_probe(struct platform_device *pdev)*/ ret =mmpcam_power_up (mcam);if (ret) - goto out_gpio2; + goto out_deinit_clk; ret =mccic_register (mcam);if (ret) - goto out_pwdn; + goto out_power_down;/* * Finally, set up our IRQ now that the core is ready to * deal with it.
@@ -473,8 +466,8 @@ static int mmpcam_probe(struct platform_device *pdev) goto out_unregister; } cam->irq = res->start; - ret =request_irq (cam->irq, mmpcam_irq,IRQF_SHARED , -"mmp-camera" , mcam); + ret =devm_request_irq (&pdev->dev, cam->irq, mmpcam_irq,IRQF_SHARED , +"mmp-camera" , mcam);if (ret ==0 ) {mmpcam_add_device (cam);return 0 ;
@@ -482,19 +475,10 @@ static int mmpcam_probe(struct platform_device *pdev) out_unregister:mccic_shutdown (mcam); -out_pwdn: +out_power_down:mmpcam_power_down (mcam); -out_gpio2: +out_deinit_clk:mcam_deinit_clk (mcam); -gpio_free (pdata->sensor_reset_gpio); -out_gpio: -gpio_free (pdata->sensor_power_gpio); -out_unmap2: -iounmap (cam->power_regs); -out_unmap1: -iounmap (mcam->regs); -out_free: -kfree (cam);return ret; }
Signature · 1 line
1.7.9.5
Hi Jonathan,
Do you have some comments?
Regards,
Libin
Quoted 47 lines
-----Original Message-----
From: Libin Yang [mailto:[email protected]]
Sent: Wednesday, July 03, 2013 1:56 PM
To: [email protected]; [email protected]
Cc: [email protected]; [email protected]; Libin Yang
Subject: [PATCH v3 0/7] marvell-ccic: update ccic driver to support some featuresThe patch set adds some feature into the marvell ccic driver
Patch 1: Support MIPI sensor
Patch 2: Support clock tree
Patch 3: reset ccic when stop streaming, which makes CCIC more stable Patch 4: refine themcam_set_contig_bufferfunction
Patch 5: add some new fmts to support
Patch 6: add SOF-EOF pair check to make the CCIC more stable Patch 7: use resource managed allocationchange log:
Patch 1:
fix the unlock issue
add some comments
remove intmipi_enabledin structmmp_camera_platform_dataget "mipi" clk at first inmmpcam_power_up()
Patch 2:
Addmcam_deinit_clkfunction
Some changes inmcam_init_clkfunction
Patch 7:
A little adjustment based patch 2 changeLibin Yang (7):
marvell-ccic: add MIPI support for marvell-ccic driver
marvell-ccic: add clock tree support for marvell-ccic driver
marvell-ccic: reset ccic phy when stop streaming for stability
marvell-ccic: refinemcam_set_contig_bufferfunction
marvell-ccic: add new formats support for marvell-ccic driver
marvell-ccic: add SOF / EOF pair check for marvell-ccic driver
marvell-ccic: switch to resource managed allocation and requestdrivers/media/platform/marvell-ccic/cafe-driver.c | 4 +- drivers/media/platform/marvell-ccic/mcam-core.c | 325 +++++++++++++++++---- drivers/media/platform/marvell-ccic/mcam-core.h | 50 +++- drivers/media/platform/marvell-ccic/mmp-driver.c | 274 ++++++++++++++--- include/media/mmp-camera.h | 18 ++ 5 files changed, 578 insertions(+), 93 deletions(-)--
1.7.9.5