msm: camera: ispif: adds 3D support
Extend the interface to include CSID and CID to be routed to VFE PIX1 interface for 3D support in ISPIF driver. Change-Id: Ibc001c5d52f1d2bc9c4639c8c40e320a5af2324a Signed-off-by: Petar Sivenov <psiven@codeaurora.org>
This commit is contained in:
parent
89bfd053bf
commit
cea9ac19b9
5 changed files with 322 additions and 46 deletions
|
@ -49,17 +49,31 @@
|
|||
#define ISPIF_TIMEOUT_ALL_US 1000000
|
||||
#define ISPIF_SOF_DEBUG_COUNT 5
|
||||
|
||||
/* 3D Threshold value according guidelines for line width 1280 */
|
||||
#define STEREO_DEFAULT_3D_THRESHOLD 0x36
|
||||
|
||||
/*
|
||||
* Overflows before restarting interface during stereo usecase
|
||||
* to give some tolerance for cases when the two sensors sync fails
|
||||
* this value is chosen by experiment
|
||||
*/
|
||||
#define MAX_PIX_OVERFLOW_ERROR_COUNT 10
|
||||
static int pix_overflow_error_count[VFE_MAX] = { 0 };
|
||||
|
||||
#undef CDBG
|
||||
#ifdef CONFIG_MSMB_CAMERA_DEBUG
|
||||
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
|
||||
#else
|
||||
#define CDBG(fmt, args...) do { } while (0)
|
||||
#define CDBG(fmt, args...)
|
||||
#endif
|
||||
|
||||
static int msm_ispif_clk_ahb_enable(struct ispif_device *ispif, int enable);
|
||||
static int ispif_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
|
||||
static long msm_ispif_subdev_ioctl_unlocked(struct v4l2_subdev *sd,
|
||||
unsigned int cmd, void *arg);
|
||||
static long msm_ispif_dispatch_cmd(enum ispif_cfg_type_t cmd,
|
||||
struct ispif_device *ispif,
|
||||
struct msm_ispif_param_data_ext *params);
|
||||
|
||||
int msm_ispif_get_clk_info(struct ispif_device *ispif_dev,
|
||||
struct platform_device *pdev);
|
||||
|
@ -249,16 +263,7 @@ static long msm_ispif_cmd_ext(struct v4l2_subdev *sd,
|
|||
}
|
||||
|
||||
mutex_lock(&ispif->mutex);
|
||||
switch (pcdata.cfg_type) {
|
||||
case ISPIF_CFG2:
|
||||
rc = msm_ispif_config2(ispif, params);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid cfg_type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
rc = msm_ispif_dispatch_cmd(pcdata.cfg_type, ispif, params);
|
||||
mutex_unlock(&ispif->mutex);
|
||||
kfree(params);
|
||||
return rc;
|
||||
|
@ -855,15 +860,34 @@ static uint16_t msm_ispif_get_cids_mask_from_cfg(
|
|||
|
||||
return cids_mask;
|
||||
}
|
||||
|
||||
static uint16_t msm_ispif_get_right_cids_mask_from_cfg(
|
||||
struct msm_ispif_right_param_entry *entry, int num_cids)
|
||||
{
|
||||
int i;
|
||||
uint16_t cids_mask = 0;
|
||||
|
||||
if (WARN_ON(!entry))
|
||||
return cids_mask;
|
||||
|
||||
for (i = 0; i < num_cids && i < MAX_CID_CH_PARAM_ENTRY; i++) {
|
||||
if (entry->cids[i] < CID_MAX)
|
||||
cids_mask |= (1 << entry->cids[i]);
|
||||
}
|
||||
|
||||
return cids_mask;
|
||||
}
|
||||
|
||||
static int msm_ispif_config(struct ispif_device *ispif,
|
||||
void *data)
|
||||
{
|
||||
int rc = 0, i = 0;
|
||||
uint16_t cid_mask;
|
||||
uint16_t cid_mask = 0;
|
||||
uint16_t cid_right_mask = 0;
|
||||
enum msm_ispif_intftype intftype;
|
||||
enum msm_ispif_vfe_intf vfe_intf;
|
||||
struct msm_ispif_param_data *params =
|
||||
(struct msm_ispif_param_data *)data;
|
||||
struct msm_ispif_param_data_ext *params =
|
||||
(struct msm_ispif_param_data_ext *)data;
|
||||
|
||||
BUG_ON(!ispif);
|
||||
BUG_ON(!params);
|
||||
|
@ -913,9 +937,15 @@ static int msm_ispif_config(struct ispif_device *ispif,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ispif->csid_version >= CSID_VERSION_V30)
|
||||
if (ispif->csid_version >= CSID_VERSION_V30) {
|
||||
msm_ispif_select_clk_mux(ispif, intftype,
|
||||
params->entries[i].csid, vfe_intf);
|
||||
if (intftype == PIX0 && params->stereo_enable &&
|
||||
params->right_entries[i].csid < CSID_MAX)
|
||||
msm_ispif_select_clk_mux(ispif, PIX1,
|
||||
params->right_entries[i].csid,
|
||||
vfe_intf);
|
||||
}
|
||||
|
||||
rc = msm_ispif_validate_intf_status(ispif, intftype, vfe_intf);
|
||||
if (rc) {
|
||||
|
@ -926,10 +956,26 @@ static int msm_ispif_config(struct ispif_device *ispif,
|
|||
|
||||
msm_ispif_sel_csid_core(ispif, intftype,
|
||||
params->entries[i].csid, vfe_intf);
|
||||
if (intftype == PIX0 && params->stereo_enable &&
|
||||
params->right_entries[i].csid < CSID_MAX)
|
||||
/* configure right stereo csid */
|
||||
msm_ispif_sel_csid_core(ispif, PIX1,
|
||||
params->right_entries[i].csid, vfe_intf);
|
||||
|
||||
cid_mask = msm_ispif_get_cids_mask_from_cfg(
|
||||
¶ms->entries[i]);
|
||||
msm_ispif_enable_intf_cids(ispif, intftype,
|
||||
cid_mask, vfe_intf, 1);
|
||||
if (params->stereo_enable)
|
||||
cid_right_mask = msm_ispif_get_right_cids_mask_from_cfg(
|
||||
¶ms->right_entries[i],
|
||||
params->entries[i].num_cids);
|
||||
else
|
||||
cid_right_mask = 0;
|
||||
if (cid_right_mask && params->stereo_enable)
|
||||
/* configure right stereo cids */
|
||||
msm_ispif_enable_intf_cids(ispif, PIX1,
|
||||
cid_right_mask, vfe_intf, 1);
|
||||
if (params->entries[i].crop_enable)
|
||||
msm_ispif_enable_crop(ispif, intftype, vfe_intf,
|
||||
params->entries[i].crop_start_pixel,
|
||||
|
@ -962,8 +1008,28 @@ static int msm_ispif_config(struct ispif_device *ispif,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void msm_ispif_config_stereo(struct ispif_device *ispif,
|
||||
struct msm_ispif_param_data_ext *params) {
|
||||
|
||||
int i;
|
||||
enum msm_ispif_vfe_intf vfe_intf;
|
||||
|
||||
for (i = 0; i < params->num; i++) {
|
||||
if (params->entries[i].intftype == PIX0 &&
|
||||
params->stereo_enable &&
|
||||
params->right_entries[i].csid < CSID_MAX) {
|
||||
vfe_intf = params->entries[i].vfe_intf;
|
||||
msm_camera_io_w_mb(0x3,
|
||||
ispif->base + ISPIF_VFE_m_OUTPUT_SEL(vfe_intf));
|
||||
msm_camera_io_w_mb(STEREO_DEFAULT_3D_THRESHOLD,
|
||||
ispif->base +
|
||||
ISPIF_VFE_m_3D_THRESHOLD(vfe_intf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits,
|
||||
struct msm_ispif_param_data *params)
|
||||
struct msm_ispif_param_data_ext *params)
|
||||
{
|
||||
uint8_t vc;
|
||||
int i, k;
|
||||
|
@ -1008,6 +1074,19 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits,
|
|||
ispif->applied_intf_cmd[vfe_intf].intf_cmd |=
|
||||
(cmd_bits << (vc * 2 + intf_type * 8));
|
||||
}
|
||||
if (intf_type == PIX0 && params->stereo_enable &&
|
||||
params->right_entries[i].cids[k] < CID_MAX) {
|
||||
cid = params->right_entries[i].cids[k];
|
||||
vc = cid / 4;
|
||||
|
||||
/* fill right stereo command */
|
||||
/* zero 2 bits */
|
||||
ispif->applied_intf_cmd[vfe_intf].intf_cmd &=
|
||||
~(0x3 << (vc * 2 + PIX1 * 8));
|
||||
/* set cmd bits */
|
||||
ispif->applied_intf_cmd[vfe_intf].intf_cmd |=
|
||||
(cmd_bits << (vc * 2 + PIX1 * 8));
|
||||
}
|
||||
}
|
||||
/* cmd for PIX0, PIX1, RDI0, RDI1 */
|
||||
if (ispif->applied_intf_cmd[vfe_intf].intf_cmd != 0xFFFFFFFF)
|
||||
|
@ -1024,7 +1103,7 @@ static void msm_ispif_intf_cmd(struct ispif_device *ispif, uint32_t cmd_bits,
|
|||
}
|
||||
|
||||
static int msm_ispif_stop_immediately(struct ispif_device *ispif,
|
||||
struct msm_ispif_param_data *params)
|
||||
struct msm_ispif_param_data_ext *params)
|
||||
{
|
||||
int i, rc = 0;
|
||||
uint16_t cid_mask = 0;
|
||||
|
@ -1052,13 +1131,22 @@ static int msm_ispif_stop_immediately(struct ispif_device *ispif,
|
|||
¶ms->entries[i]);
|
||||
msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype,
|
||||
cid_mask, params->entries[i].vfe_intf, 0);
|
||||
if (params->stereo_enable) {
|
||||
cid_mask = msm_ispif_get_right_cids_mask_from_cfg(
|
||||
¶ms->right_entries[i],
|
||||
params->entries[i].num_cids);
|
||||
if (cid_mask)
|
||||
msm_ispif_enable_intf_cids(ispif,
|
||||
params->entries[i].intftype, cid_mask,
|
||||
params->entries[i].vfe_intf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_ispif_start_frame_boundary(struct ispif_device *ispif,
|
||||
struct msm_ispif_param_data *params)
|
||||
struct msm_ispif_param_data_ext *params)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
|
@ -1074,13 +1162,14 @@ static int msm_ispif_start_frame_boundary(struct ispif_device *ispif,
|
|||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
msm_ispif_config_stereo(ispif, params);
|
||||
msm_ispif_intf_cmd(ispif, ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif,
|
||||
struct msm_ispif_param_data *params)
|
||||
struct msm_ispif_param_data_ext *params)
|
||||
{
|
||||
int rc = 0, i;
|
||||
long timeout = 0;
|
||||
|
@ -1222,10 +1311,11 @@ end:
|
|||
}
|
||||
|
||||
static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif,
|
||||
struct msm_ispif_param_data *params)
|
||||
struct msm_ispif_param_data_ext *params)
|
||||
{
|
||||
int i, rc = 0;
|
||||
uint16_t cid_mask = 0;
|
||||
uint16_t cid_right_mask = 0;
|
||||
uint32_t intf_addr;
|
||||
enum msm_ispif_vfe_intf vfe_intf;
|
||||
uint32_t stop_flag = 0;
|
||||
|
@ -1263,6 +1353,13 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif,
|
|||
for (i = 0; i < params->num; i++) {
|
||||
cid_mask =
|
||||
msm_ispif_get_cids_mask_from_cfg(¶ms->entries[i]);
|
||||
if (params->stereo_enable)
|
||||
cid_right_mask =
|
||||
msm_ispif_get_right_cids_mask_from_cfg(
|
||||
¶ms->right_entries[i],
|
||||
params->entries[i].num_cids);
|
||||
else
|
||||
cid_right_mask = 0;
|
||||
vfe_intf = params->entries[i].vfe_intf;
|
||||
|
||||
switch (params->entries[i].intftype) {
|
||||
|
@ -1294,10 +1391,24 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif,
|
|||
ISPIF_TIMEOUT_ALL_US);
|
||||
if (rc < 0)
|
||||
goto end;
|
||||
if (cid_right_mask) {
|
||||
intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1);
|
||||
rc = readl_poll_timeout(ispif->base + intf_addr,
|
||||
stop_flag,
|
||||
(stop_flag & 0xF) == 0xF,
|
||||
ISPIF_TIMEOUT_SLEEP_US,
|
||||
ISPIF_TIMEOUT_ALL_US);
|
||||
if (rc < 0)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* disable CIDs in CID_MASK register */
|
||||
msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype,
|
||||
cid_mask, vfe_intf, 0);
|
||||
if (cid_right_mask)
|
||||
msm_ispif_enable_intf_cids(ispif,
|
||||
params->entries[i].intftype, cid_right_mask,
|
||||
params->entries[i].vfe_intf, 0);
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -1318,6 +1429,14 @@ static void ispif_process_irq(struct ispif_device *ispif,
|
|||
ispif->sof_count[vfe_id].sof_cnt[PIX0]++;
|
||||
ispif->ispif_sof_debug++;
|
||||
}
|
||||
if (out[vfe_id].ispifIrqStatus1 &
|
||||
ISPIF_IRQ_STATUS_PIX_SOF_MASK) {
|
||||
if (ispif->ispif_sof_debug < ISPIF_SOF_DEBUG_COUNT*2)
|
||||
pr_err("%s: PIX1 frame id: %u\n", __func__,
|
||||
ispif->sof_count[vfe_id].sof_cnt[PIX1]);
|
||||
ispif->sof_count[vfe_id].sof_cnt[PIX1]++;
|
||||
ispif->ispif_sof_debug++;
|
||||
}
|
||||
if (out[vfe_id].ispifIrqStatus0 &
|
||||
ISPIF_IRQ_STATUS_RDI0_SOF_MASK) {
|
||||
if (ispif->ispif_rdi0_debug < ISPIF_SOF_DEBUG_COUNT)
|
||||
|
@ -1344,12 +1463,55 @@ static void ispif_process_irq(struct ispif_device *ispif,
|
|||
}
|
||||
}
|
||||
|
||||
static int msm_ispif_reconfig_3d_output(struct ispif_device *ispif,
|
||||
enum msm_ispif_vfe_intf vfe_id)
|
||||
{
|
||||
uint32_t reg_data;
|
||||
|
||||
if (WARN_ON(!ispif))
|
||||
return -EINVAL;
|
||||
|
||||
if (!((vfe_id == VFE0) || (vfe_id == VFE1))) {
|
||||
pr_err("%s;%d Cannot reconfigure 3D mode for VFE%d", __func__,
|
||||
__LINE__, vfe_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
pr_info("%s;%d Reconfiguring 3D mode for VFE%d", __func__, __LINE__,
|
||||
vfe_id);
|
||||
reg_data = 0xFFFCFFFC;
|
||||
msm_camera_io_w_mb(reg_data, ispif->base +
|
||||
ISPIF_VFE_m_INTF_CMD_0(vfe_id));
|
||||
msm_camera_io_w_mb(reg_data, ispif->base +
|
||||
ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
|
||||
|
||||
if (vfe_id == VFE0) {
|
||||
reg_data = 0;
|
||||
reg_data |= (PIX_0_VFE_RST_STB | PIX_1_VFE_RST_STB |
|
||||
STROBED_RST_EN | PIX_0_CSID_RST_STB |
|
||||
PIX_1_CSID_RST_STB | PIX_OUTPUT_0_MISR_RST_STB);
|
||||
msm_camera_io_w_mb(reg_data, ispif->base + ISPIF_RST_CMD_ADDR);
|
||||
} else {
|
||||
reg_data = 0;
|
||||
reg_data |= (PIX_0_VFE_RST_STB | PIX_1_VFE_RST_STB |
|
||||
STROBED_RST_EN | PIX_0_CSID_RST_STB |
|
||||
PIX_1_CSID_RST_STB | PIX_OUTPUT_0_MISR_RST_STB);
|
||||
msm_camera_io_w_mb(reg_data, ispif->base +
|
||||
ISPIF_RST_CMD_1_ADDR);
|
||||
}
|
||||
|
||||
reg_data = 0xFFFDFFFD;
|
||||
msm_camera_io_w_mb(reg_data, ispif->base +
|
||||
ISPIF_VFE_m_INTF_CMD_0(vfe_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
|
||||
void *data)
|
||||
{
|
||||
struct ispif_device *ispif = (struct ispif_device *)data;
|
||||
bool fatal_err = false;
|
||||
int i = 0;
|
||||
uint32_t reg_data;
|
||||
|
||||
BUG_ON(!ispif);
|
||||
BUG_ON(!out);
|
||||
|
@ -1400,6 +1562,12 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
|
|||
fatal_err = true;
|
||||
}
|
||||
|
||||
if (out[VFE0].ispifIrqStatus1 & PIX_INTF_1_OVERFLOW_IRQ) {
|
||||
pr_err_ratelimited("%s: VFE0 pix1 overflow.\n",
|
||||
__func__);
|
||||
fatal_err = true;
|
||||
}
|
||||
|
||||
if (out[VFE0].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ) {
|
||||
pr_err_ratelimited("%s: VFE0 rdi0 overflow.\n",
|
||||
__func__);
|
||||
|
@ -1432,6 +1600,12 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
|
|||
fatal_err = true;
|
||||
}
|
||||
|
||||
if (out[VFE1].ispifIrqStatus1 & PIX_INTF_1_OVERFLOW_IRQ) {
|
||||
pr_err_ratelimited("%s: VFE1 pix1 overflow.\n",
|
||||
__func__);
|
||||
fatal_err = true;
|
||||
}
|
||||
|
||||
if (out[VFE1].ispifIrqStatus0 & RAW_INTF_0_OVERFLOW_IRQ) {
|
||||
pr_err_ratelimited("%s: VFE1 rdi0 overflow.\n",
|
||||
__func__);
|
||||
|
@ -1453,6 +1627,43 @@ static inline void msm_ispif_read_irq_status(struct ispif_irq_status *out,
|
|||
ispif_process_irq(ispif, out, VFE1);
|
||||
}
|
||||
|
||||
if ((out[VFE0].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ) ||
|
||||
(out[VFE0].ispifIrqStatus1 & PIX_INTF_0_OVERFLOW_IRQ) ||
|
||||
(out[VFE0].ispifIrqStatus2 & (L_R_SOF_MISMATCH_ERR_IRQ |
|
||||
L_R_EOF_MISMATCH_ERR_IRQ | L_R_SOL_MISMATCH_ERR_IRQ))) {
|
||||
reg_data = msm_camera_io_r(ispif->base +
|
||||
ISPIF_VFE_m_OUTPUT_SEL(VFE0));
|
||||
if ((reg_data & 0x03) == VFE_PIX_INTF_SEL_3D) {
|
||||
pix_overflow_error_count[VFE0]++;
|
||||
if (pix_overflow_error_count[VFE0] >=
|
||||
MAX_PIX_OVERFLOW_ERROR_COUNT) {
|
||||
msm_ispif_reconfig_3d_output(ispif, VFE0);
|
||||
pix_overflow_error_count[VFE0] = 0;
|
||||
}
|
||||
fatal_err = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ispif->vfe_info.num_vfe > 1) {
|
||||
if ((out[VFE1].ispifIrqStatus0 & PIX_INTF_0_OVERFLOW_IRQ) ||
|
||||
(out[VFE1].ispifIrqStatus1 & PIX_INTF_0_OVERFLOW_IRQ) ||
|
||||
(out[VFE1].ispifIrqStatus2 & (L_R_SOF_MISMATCH_ERR_IRQ |
|
||||
L_R_EOF_MISMATCH_ERR_IRQ | L_R_SOL_MISMATCH_ERR_IRQ))) {
|
||||
reg_data = msm_camera_io_r(ispif->base +
|
||||
ISPIF_VFE_m_OUTPUT_SEL(VFE1));
|
||||
if ((reg_data & 0x03) == VFE_PIX_INTF_SEL_3D) {
|
||||
pix_overflow_error_count[VFE1]++;
|
||||
if (pix_overflow_error_count[VFE1] >=
|
||||
MAX_PIX_OVERFLOW_ERROR_COUNT) {
|
||||
msm_ispif_reconfig_3d_output(ispif,
|
||||
VFE1);
|
||||
pix_overflow_error_count[VFE1] = 0;
|
||||
}
|
||||
}
|
||||
fatal_err = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fatal_err == true) {
|
||||
pr_err_ratelimited("%s: fatal error, stop ispif immediately\n",
|
||||
__func__);
|
||||
|
@ -1561,61 +1772,97 @@ static void msm_ispif_release(struct ispif_device *ispif)
|
|||
pr_err("%s: failed to remove vote for AHB\n", __func__);
|
||||
}
|
||||
|
||||
static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
|
||||
static long msm_ispif_dispatch_cmd(enum ispif_cfg_type_t cmd,
|
||||
struct ispif_device *ispif,
|
||||
struct msm_ispif_param_data_ext *params)
|
||||
{
|
||||
long rc = 0;
|
||||
struct ispif_cfg_data *pcdata = (struct ispif_cfg_data *)arg;
|
||||
struct ispif_device *ispif =
|
||||
(struct ispif_device *)v4l2_get_subdevdata(sd);
|
||||
|
||||
BUG_ON(!sd);
|
||||
BUG_ON(!pcdata);
|
||||
|
||||
mutex_lock(&ispif->mutex);
|
||||
switch (pcdata->cfg_type) {
|
||||
case ISPIF_ENABLE_REG_DUMP:
|
||||
ispif->enb_dump_reg = pcdata->reg_dump; /* save dump config */
|
||||
break;
|
||||
case ISPIF_INIT:
|
||||
rc = msm_ispif_init(ispif, pcdata->csid_version);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
switch (cmd) {
|
||||
case ISPIF_CFG:
|
||||
rc = msm_ispif_config(ispif, &pcdata->params);
|
||||
rc = msm_ispif_config(ispif, params);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
case ISPIF_START_FRAME_BOUNDARY:
|
||||
rc = msm_ispif_start_frame_boundary(ispif, &pcdata->params);
|
||||
rc = msm_ispif_start_frame_boundary(ispif, params);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
case ISPIF_RESTART_FRAME_BOUNDARY:
|
||||
rc = msm_ispif_restart_frame_boundary(ispif, &pcdata->params);
|
||||
rc = msm_ispif_restart_frame_boundary(ispif, params);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
|
||||
case ISPIF_STOP_FRAME_BOUNDARY:
|
||||
rc = msm_ispif_stop_frame_boundary(ispif, &pcdata->params);
|
||||
rc = msm_ispif_stop_frame_boundary(ispif, params);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
case ISPIF_STOP_IMMEDIATELY:
|
||||
rc = msm_ispif_stop_immediately(ispif, &pcdata->params);
|
||||
rc = msm_ispif_stop_immediately(ispif, params);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
case ISPIF_RELEASE:
|
||||
msm_ispif_reset(ispif);
|
||||
msm_ispif_reset_hw(ispif);
|
||||
break;
|
||||
case ISPIF_SET_VFE_INFO:
|
||||
rc = msm_ispif_set_vfe_info(ispif, &pcdata->vfe_info);
|
||||
case ISPIF_CFG2:
|
||||
rc = msm_ispif_config2(ispif, params);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: invalid cfg_type\n", __func__);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&ispif->mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
|
||||
{
|
||||
long rc = 0;
|
||||
struct ispif_cfg_data *pcdata = (struct ispif_cfg_data *)arg;
|
||||
struct ispif_device *ispif =
|
||||
(struct ispif_device *)v4l2_get_subdevdata(sd);
|
||||
int i;
|
||||
struct msm_ispif_param_data_ext params;
|
||||
|
||||
if (WARN_ON(!sd) || WARN_ON(!pcdata))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ispif->mutex);
|
||||
switch (pcdata->cfg_type) {
|
||||
case ISPIF_ENABLE_REG_DUMP:
|
||||
/* save dump config */
|
||||
ispif->enb_dump_reg = pcdata->reg_dump;
|
||||
break;
|
||||
case ISPIF_INIT:
|
||||
rc = msm_ispif_init(ispif, pcdata->csid_version);
|
||||
msm_ispif_io_dump_reg(ispif);
|
||||
break;
|
||||
case ISPIF_SET_VFE_INFO:
|
||||
rc = msm_ispif_set_vfe_info(ispif, &pcdata->vfe_info);
|
||||
break;
|
||||
default:
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
if (pcdata->params.num > MAX_PARAM_ENTRIES) {
|
||||
pr_err("%s: invalid num entries %u\n", __func__,
|
||||
pcdata->params.num);
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
params.num = pcdata->params.num;
|
||||
for (i = 0; i < pcdata->params.num; i++)
|
||||
memcpy(¶ms.entries[i],
|
||||
&pcdata->params.entries[i],
|
||||
sizeof(struct msm_ispif_params_entry));
|
||||
params.stereo_enable = 0;
|
||||
rc = msm_ispif_dispatch_cmd(pcdata->cfg_type, ispif,
|
||||
¶ms);
|
||||
}
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&ispif->mutex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct v4l2_file_operations msm_ispif_v4l2_subdev_fops;
|
||||
|
||||
static long msm_ispif_subdev_ioctl_unlocked(struct v4l2_subdev *sd,
|
||||
|
|
|
@ -87,6 +87,12 @@
|
|||
#define MISC_LOGIC_RST_STB BIT(1)
|
||||
#define STROBED_RST_EN BIT(0)
|
||||
|
||||
#define VFE_PIX_INTF_SEL_3D 0x3
|
||||
#define PIX_OUTPUT_0_MISR_RST_STB BIT(16)
|
||||
#define L_R_SOF_MISMATCH_ERR_IRQ BIT(16)
|
||||
#define L_R_EOF_MISMATCH_ERR_IRQ BIT(17)
|
||||
#define L_R_SOL_MISMATCH_ERR_IRQ BIT(18)
|
||||
|
||||
#define ISPIF_RST_CMD_MASK 0xFE1C77FF
|
||||
#define ISPIF_RST_CMD_1_MASK 0xFFFFFFFF /* undefined */
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define ISPIF_VFE(m) ((m) * 0x200)
|
||||
|
||||
#define ISPIF_VFE_m_CTRL_0(m) (0x200 + ISPIF_VFE(m))
|
||||
#define ISPIF_VFE_m_CTRL_1(m) (0x204 + ISPIF_VFE(m))
|
||||
#define ISPIF_VFE_m_IRQ_MASK_0(m) (0x208 + ISPIF_VFE(m))
|
||||
#define ISPIF_VFE_m_IRQ_MASK_1(m) (0x20C + ISPIF_VFE(m))
|
||||
#define ISPIF_VFE_m_IRQ_MASK_2(m) (0x210 + ISPIF_VFE(m))
|
||||
|
@ -71,6 +72,12 @@
|
|||
#define MISC_LOGIC_RST_STB BIT(1)
|
||||
#define STROBED_RST_EN BIT(0)
|
||||
|
||||
#define VFE_PIX_INTF_SEL_3D 0x3
|
||||
#define PIX_OUTPUT_0_MISR_RST_STB BIT(16)
|
||||
#define L_R_SOF_MISMATCH_ERR_IRQ BIT(16)
|
||||
#define L_R_EOF_MISMATCH_ERR_IRQ BIT(17)
|
||||
#define L_R_SOL_MISMATCH_ERR_IRQ BIT(18)
|
||||
|
||||
#define ISPIF_RST_CMD_MASK 0xFE0F1FFF
|
||||
#define ISPIF_RST_CMD_1_MASK 0xFC0F1FF9
|
||||
|
||||
|
@ -78,6 +85,7 @@
|
|||
#define ISPIF_RST_CMD_1_MASK_RESTART 0x00001FF9
|
||||
|
||||
#define PIX_INTF_0_OVERFLOW_IRQ BIT(12)
|
||||
#define PIX_INTF_1_OVERFLOW_IRQ BIT(12)
|
||||
#define RAW_INTF_0_OVERFLOW_IRQ BIT(25)
|
||||
#define RAW_INTF_1_OVERFLOW_IRQ BIT(25)
|
||||
#define RAW_INTF_2_OVERFLOW_IRQ BIT(12)
|
||||
|
|
|
@ -74,6 +74,12 @@
|
|||
#define MISC_LOGIC_RST_STB BIT(1)
|
||||
#define STROBED_RST_EN BIT(0)
|
||||
|
||||
#define VFE_PIX_INTF_SEL_3D 0x3
|
||||
#define PIX_OUTPUT_0_MISR_RST_STB BIT(16)
|
||||
#define L_R_SOF_MISMATCH_ERR_IRQ BIT(16)
|
||||
#define L_R_EOF_MISMATCH_ERR_IRQ BIT(17)
|
||||
#define L_R_SOL_MISMATCH_ERR_IRQ BIT(18)
|
||||
|
||||
#define ISPIF_RST_CMD_MASK 0xFE7F1FFF
|
||||
#define ISPIF_RST_CMD_1_MASK 0xFC7F1FF9
|
||||
|
||||
|
@ -81,6 +87,7 @@
|
|||
#define ISPIF_RST_CMD_1_MASK_RESTART 0x7F1FF9
|
||||
|
||||
#define PIX_INTF_0_OVERFLOW_IRQ BIT(12)
|
||||
#define PIX_INTF_1_OVERFLOW_IRQ BIT(12)
|
||||
#define RAW_INTF_0_OVERFLOW_IRQ BIT(25)
|
||||
#define RAW_INTF_1_OVERFLOW_IRQ BIT(25)
|
||||
#define RAW_INTF_2_OVERFLOW_IRQ BIT(12)
|
||||
|
|
|
@ -36,7 +36,6 @@ enum msm_ispif_intftype {
|
|||
#define RDI1_MASK (1 << RDI1)
|
||||
#define RDI2_MASK (1 << RDI2)
|
||||
|
||||
|
||||
enum msm_ispif_vc {
|
||||
VC0,
|
||||
VC1,
|
||||
|
@ -102,10 +101,17 @@ struct msm_ispif_params_entry {
|
|||
uint16_t crop_end_pixel;
|
||||
};
|
||||
|
||||
struct msm_ispif_right_param_entry {
|
||||
enum msm_ispif_cid cids[MAX_CID_CH_PARAM_ENTRY];
|
||||
enum msm_ispif_csid csid;
|
||||
};
|
||||
|
||||
struct msm_ispif_param_data_ext {
|
||||
uint32_t num;
|
||||
struct msm_ispif_params_entry entries[MAX_PARAM_ENTRIES];
|
||||
struct msm_ispif_pack_cfg pack_cfg[CID_MAX];
|
||||
struct msm_ispif_right_param_entry right_entries[MAX_PARAM_ENTRIES];
|
||||
uint32_t stereo_enable;
|
||||
};
|
||||
|
||||
struct msm_ispif_param_data {
|
||||
|
@ -157,6 +163,8 @@ struct ispif_cfg_data_ext {
|
|||
|
||||
#define ISPIF_RDI_PACK_MODE_SUPPORT 1
|
||||
|
||||
#define ISPIF_3D_SUPPORT 1
|
||||
|
||||
#define VIDIOC_MSM_ISPIF_CFG \
|
||||
_IOWR('V', BASE_VIDIOC_PRIVATE, struct ispif_cfg_data)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue