Loading drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +290 −46 Original line number Diff line number Diff line /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -49,17 +49,31 @@ #define ISPIF_TIMEOUT_ALL_US 1000000 #define ISPIF_SOF_DEBUG_COUNT 0 /* 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); Loading Loading @@ -238,16 +252,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; Loading Loading @@ -842,15 +847,33 @@ 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; BUG_ON(!entry); for (i = 0; i < num_cids && i < MAX_CID_CH_v2; 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); Loading Loading @@ -900,9 +923,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) { Loading @@ -913,10 +942,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, Loading Loading @@ -949,8 +994,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; Loading Loading @@ -995,6 +1060,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) Loading @@ -1011,7 +1089,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; Loading Loading @@ -1039,13 +1117,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; Loading @@ -1061,13 +1148,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; Loading @@ -1088,10 +1176,11 @@ static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif, } 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; Loading Loading @@ -1129,6 +1218,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) { Loading Loading @@ -1160,10 +1256,24 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, ISPIF_TIMEOUT_ALL_US); if (rc < 0) pr_err("ISPIF stop frame boundary timeout\n"); 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) pr_err("ISPIF stop frame boundary timeout\n"); } /* 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: Loading @@ -1184,6 +1294,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) Loading @@ -1210,12 +1328,54 @@ 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; BUG_ON(!ispif); 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); Loading Loading @@ -1266,6 +1426,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__); Loading Loading @@ -1298,6 +1464,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__); Loading @@ -1319,6 +1491,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__); Loading Loading @@ -1430,61 +1639,96 @@ 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_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; } 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; BUG_ON(!sd); BUG_ON(!pcdata); 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: pr_err("%s: invalid cfg_type\n", __func__); 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, Loading drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h +8 −0 Original line number Diff line number Diff line Loading @@ -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)) Loading Loading @@ -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 Loading @@ -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) Loading drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) Loading include/uapi/media/msmb_ispif.h +9 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ enum msm_ispif_intftype { #define RDI1_MASK (1 << RDI1) #define RDI2_MASK (1 << RDI2) enum msm_ispif_vc { VC0, VC1, Loading Loading @@ -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_v2]; 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 { Loading Loading @@ -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 Loading
drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +290 −46 Original line number Diff line number Diff line /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -49,17 +49,31 @@ #define ISPIF_TIMEOUT_ALL_US 1000000 #define ISPIF_SOF_DEBUG_COUNT 0 /* 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); Loading Loading @@ -238,16 +252,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; Loading Loading @@ -842,15 +847,33 @@ 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; BUG_ON(!entry); for (i = 0; i < num_cids && i < MAX_CID_CH_v2; 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); Loading Loading @@ -900,9 +923,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) { Loading @@ -913,10 +942,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, Loading Loading @@ -949,8 +994,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; Loading Loading @@ -995,6 +1060,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) Loading @@ -1011,7 +1089,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; Loading Loading @@ -1039,13 +1117,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; Loading @@ -1061,13 +1148,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; Loading @@ -1088,10 +1176,11 @@ static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif, } 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; Loading Loading @@ -1129,6 +1218,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) { Loading Loading @@ -1160,10 +1256,24 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, ISPIF_TIMEOUT_ALL_US); if (rc < 0) pr_err("ISPIF stop frame boundary timeout\n"); 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) pr_err("ISPIF stop frame boundary timeout\n"); } /* 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: Loading @@ -1184,6 +1294,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) Loading @@ -1210,12 +1328,54 @@ 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; BUG_ON(!ispif); 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); Loading Loading @@ -1266,6 +1426,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__); Loading Loading @@ -1298,6 +1464,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__); Loading @@ -1319,6 +1491,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__); Loading Loading @@ -1430,61 +1639,96 @@ 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_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; } 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; BUG_ON(!sd); BUG_ON(!pcdata); 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: pr_err("%s: invalid cfg_type\n", __func__); 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, Loading
drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h +8 −0 Original line number Diff line number Diff line Loading @@ -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)) Loading Loading @@ -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 Loading @@ -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) Loading
drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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) Loading
include/uapi/media/msmb_ispif.h +9 −1 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ enum msm_ispif_intftype { #define RDI1_MASK (1 << RDI1) #define RDI2_MASK (1 << RDI2) enum msm_ispif_vc { VC0, VC1, Loading Loading @@ -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_v2]; 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 { Loading Loading @@ -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