Skip to content

Commit

Permalink
[media] marvell-ccic: add MIPI support for marvell-ccic driver
Browse files Browse the repository at this point in the history
This patch adds the MIPI support for marvell-ccic.
Board driver should determine whether using MIPI or not.

Signed-off-by: Albert Wang <twang13@marvell.com>
Signed-off-by: Libin Yang <lbyang@marvell.com>
Acked-by: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
  • Loading branch information
Libin Yang authored and Mauro Carvalho Chehab committed Jul 26, 2013
1 parent 187d42d commit 05fed81
Show file tree
Hide file tree
Showing 4 changed files with 244 additions and 13 deletions.
4 changes: 3 additions & 1 deletion drivers/media/platform/marvell-ccic/cafe-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,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
Expand All @@ -414,6 +414,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)
Expand Down
80 changes: 76 additions & 4 deletions drivers/media/platform/marvell-ccic/mcam-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
Expand Down Expand Up @@ -253,6 +254,45 @@ static void mcam_ctlr_stop(struct mcam_camera *cam)
mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE);
}

static void mcam_enable_mipi(struct mcam_camera *mcam)
{
/* Using MIPI mode and enable MIPI */
cam_dbg(mcam, "camera: DPHY3=0x%x, DPHY5=0x%x, DPHY6=0x%x\n",
mcam->dphy[0], mcam->dphy[1], mcam->dphy[2]);
mcam_reg_write(mcam, REG_CSI2_DPHY3, mcam->dphy[0]);
mcam_reg_write(mcam, REG_CSI2_DPHY5, mcam->dphy[1]);
mcam_reg_write(mcam, REG_CSI2_DPHY6, mcam->dphy[2]);

if (!mcam->mipi_enabled) {
if (mcam->lane > 4 || mcam->lane <= 0) {
cam_warn(mcam, "lane number error\n");
mcam->lane = 1; /* set the default value */
}
/*
* 0x41 actives 1 lane
* 0x43 actives 2 lanes
* 0x45 actives 3 lanes (never happen)
* 0x47 actives 4 lanes
*/
mcam_reg_write(mcam, REG_CSI2_CTRL0,
CSI2_C0_MIPI_EN | CSI2_C0_ACT_LANE(mcam->lane));
mcam_reg_write(mcam, REG_CLKCTRL,
(mcam->mclk_src << 29) | mcam->mclk_div);

mcam->mipi_enabled = true;
}
}

static void mcam_disable_mipi(struct mcam_camera *mcam)
{
/* Using Parallel mode or disable MIPI */
mcam_reg_write(mcam, REG_CSI2_CTRL0, 0x0);
mcam_reg_write(mcam, REG_CSI2_DPHY3, 0x0);
mcam_reg_write(mcam, REG_CSI2_DPHY5, 0x0);
mcam_reg_write(mcam, REG_CSI2_DPHY6, 0x0);
mcam->mipi_enabled = false;
}

/* ------------------------------------------------------------------- */

#ifdef MCAM_MODE_VMALLOC
Expand Down Expand Up @@ -656,6 +696,13 @@ static void mcam_ctlr_image(struct mcam_camera *cam)
*/
mcam_reg_write_mask(cam, REG_CTRL0, C0_SIF_HVSYNC,
C0_SIFM_MASK);

/*
* This field controls the generation of EOF(DVP only)
*/
if (cam->bus_type != V4L2_MBUS_CSI2)
mcam_reg_set_bit(cam, REG_CTRL0,
C0_EOF_VSYNC | C0_VEDGE_CTRL);
}


Expand Down Expand Up @@ -753,15 +800,21 @@ static void mcam_ctlr_stop_dma(struct mcam_camera *cam)
/*
* Power up and down.
*/
static void mcam_ctlr_power_up(struct mcam_camera *cam)
static int mcam_ctlr_power_up(struct mcam_camera *cam)
{
unsigned long flags;
int ret;

spin_lock_irqsave(&cam->dev_lock, flags);
cam->plat_power_up(cam);
ret = cam->plat_power_up(cam);
if (ret) {
spin_unlock_irqrestore(&cam->dev_lock, flags);
return ret;
}
mcam_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN);
spin_unlock_irqrestore(&cam->dev_lock, flags);
msleep(5); /* Just to be sure */
return 0;
}

static void mcam_ctlr_power_down(struct mcam_camera *cam)
Expand Down Expand Up @@ -869,6 +922,17 @@ static int mcam_read_setup(struct mcam_camera *cam)
spin_lock_irqsave(&cam->dev_lock, flags);
clear_bit(CF_DMA_ACTIVE, &cam->flags);
mcam_reset_buffers(cam);
/*
* Update CSI2_DPHY value
*/
if (cam->calc_dphy)
cam->calc_dphy(cam);
cam_dbg(cam, "camera: DPHY sets: dphy3=0x%x, dphy5=0x%x, dphy6=0x%x\n",
cam->dphy[0], cam->dphy[1], cam->dphy[2]);
if (cam->bus_type == V4L2_MBUS_CSI2)
mcam_enable_mipi(cam);
else
mcam_disable_mipi(cam);
mcam_ctlr_irq_enable(cam);
cam->state = S_STREAMING;
if (!test_bit(CF_SG_RESTART, &cam->flags))
Expand Down Expand Up @@ -1475,7 +1539,9 @@ static int mcam_v4l_open(struct file *filp)
ret = mcam_setup_vb2(cam);
if (ret)
goto out;
mcam_ctlr_power_up(cam);
ret = mcam_ctlr_power_up(cam);
if (ret)
goto out;
__mcam_cam_reset(cam);
mcam_set_config_needed(cam, 1);
}
Expand All @@ -1498,10 +1564,12 @@ static int mcam_v4l_release(struct file *filp)
if (cam->users == 0) {
mcam_ctlr_stop_dma(cam);
mcam_cleanup_vb2(cam);
mcam_disable_mipi(cam);
mcam_ctlr_power_down(cam);
if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read)
mcam_free_dma_bufs(cam);
}

mutex_unlock(&cam->s_mutex);
return 0;
}
Expand Down Expand Up @@ -1787,7 +1855,11 @@ int mccic_resume(struct mcam_camera *cam)

mutex_lock(&cam->s_mutex);
if (cam->users > 0) {
mcam_ctlr_power_up(cam);
ret = mcam_ctlr_power_up(cam);
if (ret) {
mutex_unlock(&cam->s_mutex);
return ret;
}
__mcam_cam_reset(cam);
} else {
mcam_ctlr_power_down(cam);
Expand Down
37 changes: 34 additions & 3 deletions drivers/media/platform/marvell-ccic/mcam-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,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
Expand Down Expand Up @@ -225,6 +242,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 */
Expand Down Expand Up @@ -293,13 +321,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 */
Expand Down
Loading

0 comments on commit 05fed81

Please sign in to comment.